# HG changeset patch # User Mark Doliner # Date 1085333265 0 # Node ID 7ab20f8291907f1b16f6425c0794ec796bb2d5f8 # Parent 697e169dac12ab787ab6464d18115a1e2a267fb8 [gaim-migrate @ 9806] Siege updated the code for creating right-click menu's for buddies, chats, groups, etc. It uses more stuff from the blist API and less stuff from multi.h. It also combines the code for right-click menus for chats, buddies, etc. (all types of blist nodes). So PRPLs and plugins can easily add right-click menu options to anything in the buddy list in a clean way. committer: Tailor Script diff -r 697e169dac12 -r 7ab20f829190 src/blist.c --- a/src/blist.c Sun May 23 08:06:38 2004 +0000 +++ b/src/blist.c Sun May 23 17:27:45 2004 +0000 @@ -2720,25 +2720,28 @@ /* XXX: end compat crap */ -GList *gaim_buddy_get_extended_menu(GaimBuddy *b) { +GList *gaim_blist_node_get_extended_menu(GaimBlistNode *n) { GList *menu = NULL; - gaim_signal_emit(gaim_blist_get_handle(), "buddy-extended-menu", - b, &menu); + + g_return_val_if_fail(n, NULL); + + gaim_signal_emit(gaim_blist_get_handle(), + "blist-node-extended-menu", + n, &menu); return menu; } -GList *gaim_chat_get_extended_menu(GaimChat *c) { - GList *menu = NULL; - gaim_signal_emit(gaim_blist_get_handle(), "chat-extended-menu", - c, &menu); - return menu; -} - -GList *gaim_group_get_extended_menu(GaimGroup *g) { - GList *menu = NULL; - gaim_signal_emit(gaim_blist_get_handle(), "group-extended-menu", - g, &menu); - return menu; + +GaimBlistNodeAction * +gaim_blist_node_action_new(char *label, + void (*callback)(GaimBlistNode *, gpointer), + gpointer data) +{ + GaimBlistNodeAction *act = g_new0(GaimBlistNodeAction, 1); + act->label = label; + act->callback = callback; + act->data = data; + return act; } @@ -2812,20 +2815,11 @@ GAIM_SUBTYPE_BLIST_BUDDY)); gaim_signal_register(handle, "update-idle", gaim_marshal_VOID, NULL, 0); - gaim_signal_register(handle, "buddy-extended-menu", + + gaim_signal_register(handle, "blist-node-extended-menu", gaim_marshal_VOID__POINTER_POINTER, NULL, 2, gaim_value_new(GAIM_TYPE_SUBTYPE, - GAIM_SUBTYPE_BLIST_BUDDY), - gaim_value_new(GAIM_TYPE_BOXED, "GList **")); - gaim_signal_register(handle, "chat-extended-menu", - gaim_marshal_VOID__POINTER_POINTER, NULL, 2, - gaim_value_new(GAIM_TYPE_SUBTYPE, - GAIM_SUBTYPE_BLIST_CHAT), - gaim_value_new(GAIM_TYPE_BOXED, "GList **")); - gaim_signal_register(handle, "group-extended-menu", - gaim_marshal_VOID__POINTER_POINTER, NULL, 2, - gaim_value_new(GAIM_TYPE_SUBTYPE, - GAIM_SUBTYPE_BLIST_GROUP), + GAIM_SUBTYPE_BLIST_NODE), gaim_value_new(GAIM_TYPE_BOXED, "GList **")); } @@ -2834,3 +2828,4 @@ { gaim_signals_unregister_by_instance(gaim_blist_get_handle()); } + diff -r 697e169dac12 -r 7ab20f829190 src/blist.h --- a/src/blist.h Sun May 23 08:06:38 2004 +0000 +++ b/src/blist.h Sun May 23 17:27:45 2004 +0000 @@ -34,6 +34,8 @@ typedef struct _GaimBlistUiOps GaimBlistUiOps; typedef struct _GaimBlistNode GaimBlistNode; +typedef struct _GaimBlistNodeAction GaimBlistNodeAction; + typedef struct _GaimChat GaimChat; typedef struct _GaimGroup GaimGroup; typedef struct _GaimContact GaimContact; @@ -183,6 +185,14 @@ void (*request_add_group)(void); }; + +struct _GaimBlistNodeAction { + char *label; + void (*callback)(GaimBlistNode *, gpointer); + gpointer data; +}; + + #ifdef __cplusplus extern "C" { #endif @@ -857,22 +867,23 @@ /** - * Retrieves the extended menu items for a buddy. - * @param b The buddy to obtain the extended menu items for -*/ -GList *gaim_buddy_get_extended_menu(GaimBuddy *b); + * Retrieves the extended menu items for a buddy list node. + * @param n The blist node for which to obtain the extended menu items. + * @return list of GaimBlistNodeAction items, as harvested by the + * blist-node-extended-menu signal. + */ +GList *gaim_blist_node_get_extended_menu(GaimBlistNode *n); + /** - * Retrieves the extended menu items for a chat. - * @param c The chat to obtain the extended menu items for -*/ -GList *gaim_chat_get_extended_menu(GaimChat *c); - -/** - * Retrieves the extended menu items for a group. - * @param g The group to obtain the extended menu items for -*/ -GList *gaim_group_get_extended_menu(GaimGroup *g); + * Creates a new GaimBlistNodeAction. + * @param label The text label to display for this action. + * @param callback The function to be called when the action is used on + * a selected GaimBlistNode. + * @param data Additional data, to be passed to the callback + */ +GaimBlistNodeAction *gaim_blist_node_action_new(char *label, + void (*callback)(GaimBlistNode *, gpointer), gpointer data); /**************************************************************************/ diff -r 697e169dac12 -r 7ab20f829190 src/gtkblist.c --- a/src/gtkblist.c Sun May 23 08:06:38 2004 +0000 +++ b/src/gtkblist.c Sun May 23 17:27:45 2004 +0000 @@ -1059,19 +1059,75 @@ } } -static void gaim_proto_menu_cb(GtkMenuItem *item, GaimBuddy *b) + +static void +blist_node_menu_cb(GtkMenuItem *item, GaimBlistNode *node) +{ + GaimBlistNodeAction *act; + act = (GaimBlistNodeAction *) g_object_get_data(G_OBJECT(item), + "gaimcallback"); + if(act->callback) + act->callback(node, act->data); +} + + +static void +append_blist_node_action (GtkWidget *menu, GaimBlistNodeAction *act, + GaimBlistNode *node, gboolean *dup_separator) { - struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); - if (pbm->callback) - pbm->callback(pbm->gc, b->name); + if(act == NULL) { + if(! *dup_separator) { + gaim_separator(menu); + *dup_separator = TRUE; + } + } else { + GtkWidget *menuitem; + + *dup_separator = FALSE; + + menuitem = gtk_menu_item_new_with_mnemonic(act->label); + g_object_set_data(G_OBJECT(menuitem), "gaimcallback", act); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(blist_node_menu_cb), node); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + } } + +static void +append_blist_node_proto_menu (GtkWidget *menu, GaimConnection *gc, GaimBlistNode *node) +{ + GList *l, *ll; + gboolean dup_separator = FALSE; + GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); + + if(!prpl_info || !prpl_info->blist_node_menu) + return; + + for(l = ll = prpl_info->blist_node_menu(node); l; l = l->next) { + GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; + append_blist_node_action(menu, act, node, &dup_separator); + } + g_list_free(ll); +} + + +static void +append_blist_node_extended_menu (GtkWidget *menu, GaimBlistNode *node) +{ + GList *l, *ll; + gboolean dup_separator = FALSE; + + for(l = ll = gaim_blist_node_get_extended_menu(node); l; l = l->next) { + GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; + append_blist_node_action(menu, act, node, &dup_separator); + } + g_list_free(ll); +} + + static void make_buddy_menu(GtkWidget *menu, GaimPluginProtocolInfo *prpl_info, GaimBuddy *b) { - GList *list = NULL, *l = NULL; - gboolean dup_separator = FALSE; - GtkWidget *menuitem; - if (prpl_info && prpl_info->get_info) { gaim_new_item_from_stock(menu, _("Get _Info"), GAIM_STOCK_INFO, G_CALLBACK(gtk_blist_menu_info_cb), b, 0, 0, NULL); @@ -1083,65 +1139,14 @@ gaim_new_item_from_stock(menu, _("View _Log"), NULL, G_CALLBACK(gtk_blist_menu_showlog_cb), b, 0, 0, NULL); - if (prpl_info && prpl_info->buddy_menu) { - list = prpl_info->buddy_menu(b->account->gc, b->name); - - for(l = list; l; l = l->next) { - struct proto_buddy_menu *pbm = l->data; - - /* draw NULL menu items as a separator. - Also, do some simple checking to prevent - doubled-up separators */ - if(pbm == NULL) { - if(! dup_separator) { - gaim_separator(menu); - dup_separator = TRUE; - } - continue; - } else { - dup_separator = FALSE; - } - - menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); - g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(gaim_proto_menu_cb), b); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - } - g_list_free(list); - } - - /* check for additional menu items which may be added by other - plugins. */ - list = gaim_buddy_get_extended_menu(b); - for(l = list; l; l = l->next) { - struct proto_buddy_menu *pbm = l->data; - - /* draw NULL menu items as a separator. see previous, - identical-looking code. */ - if(pbm == NULL) { - if(! dup_separator) { - gaim_separator(menu); - dup_separator = TRUE; - } - continue; - } else { - dup_separator = FALSE; - } - - menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); - g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(gaim_proto_menu_cb), b); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - } - g_list_free(list); + append_blist_node_proto_menu(menu, b->account->gc, (GaimBlistNode *) b); + append_blist_node_extended_menu(menu, (GaimBlistNode *) b); /* moving on to the old ui-specific plugin menus */ - gaim_signal_emit(gaim_gtk_blist_get_handle(), - "drawing-menu", menu, b); + gaim_signal_emit(gaim_gtk_blist_get_handle(), "drawing-menu", menu, b); gaim_separator(menu); + gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, G_CALLBACK(gtk_blist_menu_alias_cb), b, 0, 0, NULL); gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, @@ -1183,20 +1188,11 @@ return FALSE; } -static void gaim_proto_group_menu_cb(GtkMenuItem *item, GaimGroup *g) -{ - struct proto_group_menu *pgm = g_object_get_data(G_OBJECT(item), "gaimcallback"); - if (pgm->callback) - pgm->callback(g); -} static GtkWidget * create_group_menu (GaimBlistNode *node, GaimGroup *g) { GtkWidget *menu; - GList *list = NULL, *l = NULL; - gboolean dup_separator = FALSE; - GtkWidget *menuitem; menu = gtk_menu_new(); gaim_new_item_from_stock(menu, _("Add a _Buddy"), GTK_STOCK_ADD, @@ -1208,39 +1204,11 @@ gaim_new_item_from_stock(menu, _("_Rename"), NULL, G_CALLBACK(show_rename_group), node, 0, 0, NULL); - list = gaim_group_get_extended_menu(g); - for(l = list; l; l = l->next) { - struct proto_group_menu *pgm = l->data; - - /* draw NULL menu items as a separator. see previous, - identical-looking code. (in make_buddy_menu)*/ - if(pgm == NULL) { - if(! dup_separator) { - gaim_separator(menu); - dup_separator = TRUE; - } - continue; - } else { - dup_separator = FALSE; - } - - menuitem = gtk_menu_item_new_with_mnemonic(pgm->label); - g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pgm); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(gaim_proto_group_menu_cb), g); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - } - g_list_free(list); + append_blist_node_extended_menu(menu, node); return menu; } -static void gaim_proto_chat_menu_cb(GtkMenuItem *item, GaimChat *c) -{ - struct proto_chat_menu *pcm = g_object_get_data(G_OBJECT(item), "gaimcallback"); - if (pcm->callback) - pcm->callback(pcm->gc, c->components); -} static GtkWidget * create_chat_menu (GaimBlistNode *node, @@ -1249,78 +1217,25 @@ GaimPluginProtocolInfo *prpl_info) { GtkWidget *menu; - GList *list, *l; - GtkWidget *menuitem; - gboolean dup_separator = FALSE; - gboolean autojoin = (gaim_blist_node_get_bool(node, - "gtk-autojoin") || (gaim_blist_node_get_string(node, - "gtk-autojoin") != NULL)); + gboolean autojoin; menu = gtk_menu_new(); + autojoin = (gaim_blist_node_get_bool(node, "gtk-autojoin") || + (gaim_blist_node_get_string(node, "gtk-autojoin") != NULL)); + gaim_new_item_from_stock(menu, _("_Join"), GAIM_STOCK_CHAT, - G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); + G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); gaim_new_check_item(menu, _("Auto-Join"), - G_CALLBACK(gtk_blist_menu_autojoin_cb), node, - autojoin); - - if (prpl_info && prpl_info->chat_menu) { - list = prpl_info->chat_menu(c->account->gc, c->components); - while (list) { - struct proto_chat_menu *pcm = list->data; - - /* draw NULL menu items as a separator. - Also, do some simple checking to prevent - doubled-up separators */ - if(pcm == NULL) { - if(! dup_separator) { - gaim_separator(menu); - dup_separator = TRUE; - } - continue; - } else { - dup_separator = FALSE; - } - - menuitem = gtk_menu_item_new_with_mnemonic(pcm->label); - g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pcm); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(gaim_proto_chat_menu_cb), c); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - list = list->next; - } - } - - /* check for additional menu items which may be added by other - plugins. */ - list = gaim_chat_get_extended_menu(c); - for(l = list; l; l = l->next) { - struct proto_chat_menu *pcm = l->data; - - /* draw NULL menu items as a separator. see previous, - identical-looking code. */ - if(pcm == NULL) { - if(! dup_separator) { - gaim_separator(menu); - dup_separator = TRUE; - } - continue; - } else { - dup_separator = FALSE; - } - - menuitem = gtk_menu_item_new_with_mnemonic(pcm->label); - g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pcm); - g_signal_connect(G_OBJECT(menuitem), "activate", - G_CALLBACK(gaim_proto_chat_menu_cb), c); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - } - g_list_free(list); + G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); + + append_blist_node_proto_menu(menu, c->account->gc, node); + append_blist_node_extended_menu(menu, node); /* moving on to the old ui-specific plugin menus */ - gaim_signal_emit(gaim_gtk_blist_get_handle(), - "drawing-menu", menu, c); + gaim_signal_emit(gaim_gtk_blist_get_handle(), "drawing-menu", menu, c); gaim_separator(menu); + gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, diff -r 697e169dac12 -r 7ab20f829190 src/multi.h --- a/src/multi.h Sun May 23 08:06:38 2004 +0000 +++ b/src/multi.h Sun May 23 17:27:45 2004 +0000 @@ -24,25 +24,6 @@ #ifndef _MULTI_H_ #define _MULTI_H_ -#include "account.h" - -struct proto_buddy_menu { - char *label; - void (*callback)(GaimConnection *, const char *); - GaimConnection *gc; -}; - -struct proto_chat_menu { - char *label; - void (*callback)(GaimConnection *, GHashTable *); - GaimConnection *gc; -}; - -struct proto_group_menu { - char *label; - void (*callback)(GaimGroup *); -}; - struct proto_chat_entry { char *label; char *identifier; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/gg/gg.c --- a/src/protocols/gg/gg.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/gg/gg.c Sun May 23 17:27:45 2004 +0000 @@ -1,6 +1,6 @@ /* * gaim - Gadu-Gadu Protocol Plugin - * $Id: gg.c 9791 2004-05-22 17:33:38Z lschiere $ + * $Id: gg.c 9806 2004-05-23 17:27:45Z thekingant $ * * Copyright (C) 2001 Arkadiusz Mi¶kiewicz * @@ -26,8 +26,8 @@ #include "account.h" #include "accountopt.h" +#include "blist.h" #include "debug.h" -#include "multi.h" #include "notify.h" #include "proxy.h" #include "prpl.h" @@ -244,27 +244,35 @@ } /* Enhance these functions, more options and such stuff */ -static GList *agg_buddy_menu(GaimConnection *gc, const char *who) +static GList *agg_buddy_menu(GaimBuddy *buddy) { GList *m = NULL; - struct proto_buddy_menu *pbm; - GaimBuddy *b = gaim_find_buddy(gc->account, who); + GaimBlistNodeAction *act; + static char buf[AGG_BUF_LEN]; + g_snprintf(buf, sizeof(buf), _("Status: %s"), get_away_text(buddy->uc)); - if (!b) { - return m; - } - - pbm = g_new0(struct proto_buddy_menu, 1); - g_snprintf(buf, sizeof(buf), _("Status: %s"), get_away_text(b->uc)); - pbm->label = buf; - pbm->callback = NULL; - pbm->gc = gc; - m = g_list_append(m, pbm); + /* um... this seems silly. since in this pass, I'm only converting + over the menu building, I'm not going to mess with it though */ + /* XXX: shouldn't this be in the tooltip instead? */ + act = gaim_blist_node_action_new(buf, NULL, NULL); + m = g_list_append(m, act); return m; } + +static GList * +agg_blist_node_menu(GaimBlistNode *node) +{ + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return agg_buddy_menu((GaimBuddy *) node); + } else { + return NULL; + } +} + + static void agg_load_buddy_list(GaimConnection *gc, char *buddylist) { struct agg_data *gd = (struct agg_data *)gc->proto_data; @@ -1530,7 +1538,7 @@ NULL, NULL, agg_away_states, - agg_buddy_menu, + agg_blist_node_menu, NULL, agg_login, agg_close, @@ -1575,7 +1583,6 @@ NULL, NULL, NULL, - NULL }; static GaimPluginInfo info = @@ -1587,7 +1594,7 @@ NULL, /**< dependencies */ GAIM_PRIORITY_DEFAULT, /**< priority */ - "prpl-gg", /**< id */ + "prpl-gg", /**< id */ "Gadu-Gadu", /**< name */ VERSION, /**< version */ /** summary */ @@ -1613,9 +1620,9 @@ GaimAccountOption *option; option = gaim_account_option_string_new(_("Nick"), "nick", - "Gadu-Gadu User"); + "Gadu-Gadu User"); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, - option); + option); my_protocol = plugin; } diff -r 697e169dac12 -r 7ab20f829190 src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/irc/irc.c Sun May 23 17:27:45 2004 +0000 @@ -25,15 +25,16 @@ #include "internal.h" -#include "plugin.h" #include "accountopt.h" -#include "multi.h" -#include "prpl.h" +#include "blist.h" #include "conversation.h" +#include "debug.h" +#include "multi.h" #include "notify.h" -#include "debug.h" -#include "blist.h" +#include "prpl.h" +#include "plugin.h" #include "util.h" + #include "irc.h" static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string); @@ -143,16 +144,31 @@ return list; } -static GList *irc_buddy_menu(GaimConnection *gc, const char *who) + +static void irc_dccsend_send_ask_menu(GaimBlistNode *node, gpointer data) +{ + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc =gaim_account_get_connection(buddy->account); + + irc_dccsend_send_ask(gc, buddy->name); +} + + +static GList *irc_blist_node_menu(GaimBlistNode *node) { GList *m = NULL; - struct proto_buddy_menu *pbm; - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send File"); - pbm->callback = irc_dccsend_send_ask; - pbm->gc = gc; - m = g_list_append(m, pbm); + GaimBlistNodeAction *act; + + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + act = gaim_blist_node_action_new(_("Send File"), + irc_dccsend_send_ask_menu, NULL); + m = g_list_append(m, act); + } return m; } @@ -545,7 +561,7 @@ NULL, NULL, irc_away_states, - irc_buddy_menu, + irc_blist_node_menu, irc_chat_join_info, irc_login, irc_close, @@ -589,7 +605,6 @@ NULL, irc_roomlist_get_list, irc_roomlist_cancel, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/irc/irc.h --- a/src/protocols/irc/irc.h Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/irc/irc.h Sun May 23 17:27:45 2004 +0000 @@ -25,7 +25,6 @@ #include -#include "multi.h" #include "roomlist.h" #define IRC_DEFAULT_SERVER "irc.freenode.net" diff -r 697e169dac12 -r 7ab20f829190 src/protocols/jabber/buddy.c --- a/src/protocols/jabber/buddy.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/jabber/buddy.c Sun May 23 17:27:45 2004 +0000 @@ -835,93 +835,145 @@ xmlnode_free(presence); } -static void jabber_buddy_make_invisible(GaimConnection *gc, const char *name) +static void jabber_buddy_make_invisible(GaimBlistNode *node, gpointer data) { - JabberStream *js = gc->proto_data; - jabber_buddy_set_invisibility(js, name, TRUE); + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + jabber_buddy_set_invisibility(js, buddy->name, TRUE); } -static void jabber_buddy_make_visible(GaimConnection *gc, const char *name) +static void jabber_buddy_make_visible(GaimBlistNode *node, gpointer data) { - JabberStream *js = gc->proto_data; - jabber_buddy_set_invisibility(js, name, FALSE); -} + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; -static void jabber_buddy_cancel_presence_notification(GaimConnection *gc, - const char *name) -{ - JabberStream *js = gc->proto_data; + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - /* I wonder if we should prompt the user before doing this */ - jabber_presence_subscription_set(js, name, "unsubscribed"); + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + jabber_buddy_set_invisibility(js, buddy->name, FALSE); } -static void jabber_buddy_rerequest_auth(GaimConnection *gc, const char *name) +static void jabber_buddy_cancel_presence_notification(GaimBlistNode *node, + gpointer data) { - JabberStream *js = gc->proto_data; + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - jabber_presence_subscription_set(js, name, "subscribe"); + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + /* I wonder if we should prompt the user before doing this */ + jabber_presence_subscription_set(js, buddy->name, "unsubscribed"); } -static void jabber_buddy_unsubscribe(GaimConnection *gc, const char *name) +static void jabber_buddy_rerequest_auth(GaimBlistNode *node, gpointer data) { - JabberStream *js = gc->proto_data; + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - jabber_presence_subscription_set(js, name, "unsubscribe"); + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + jabber_presence_subscription_set(js, buddy->name, "subscribe"); } -GList *jabber_buddy_menu(GaimConnection *gc, const char *name) + +static void jabber_buddy_unsubscribe(GaimBlistNode *node, gpointer data) { + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + jabber_presence_subscription_set(js, buddy->name, "unsubscribe"); +} + + +GList *jabber_buddy_menu(GaimBuddy *buddy) +{ + GaimConnection *gc = gaim_account_get_connection(buddy->account); + JabberStream *js = gc->proto_data; + JabberBuddy *jb = jabber_buddy_find(js, buddy->name, TRUE); + GList *m = NULL; - struct proto_buddy_menu *pbm; - JabberStream *js = gc->proto_data; - JabberBuddy *jb = jabber_buddy_find(js, name, TRUE); + GaimBlistNodeAction *act; if(!jb) return m; - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send File"); - pbm->callback = jabber_si_xfer_ask_send; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Send File"), + jabber_si_xfer_ask_send, NULL); + m = g_list_append(m, act); /* XXX: fix the NOT ME below */ if(js->protocol_version == JABBER_PROTO_0_9 /* && NOT ME */) { - pbm = g_new0(struct proto_buddy_menu, 1); if(jb->invisible & JABBER_INVIS_BUDDY) { - pbm->label = _("Un-hide From"); - pbm->callback = jabber_buddy_make_visible; + act = gaim_blist_node_action_new(_("Un-hide From"), + jabber_buddy_make_visible, NULL); } else { - pbm->label = _("Temporarily Hide From"); - pbm->callback = jabber_buddy_make_invisible; + act = gaim_blist_node_action_new(_("Temporarily Hide From"), + jabber_buddy_make_invisible, NULL); } - pbm->gc = gc; - m = g_list_append(m, pbm); + m = g_list_append(m, act); } if(jb->subscription & JABBER_SUB_FROM /* && NOT ME */) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Cancel Presence Notification"); - pbm->callback = jabber_buddy_cancel_presence_notification; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Cancel Presence Notification"), + jabber_buddy_cancel_presence_notification, NULL); + m = g_list_append(m, act); } if(!(jb->subscription & JABBER_SUB_TO)) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("(Re-)Request authorization"); - pbm->callback = jabber_buddy_rerequest_auth; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("(Re-)Request authorization"), + jabber_buddy_rerequest_auth, NULL); + m = g_list_append(m, act); + } else /* if(NOT ME) */{ - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Unsubscribe"); - pbm->callback = jabber_buddy_unsubscribe; - pbm->gc = gc; - m = g_list_append(m, pbm); + + /* shouldn't this just happen automatically when the buddy is + removed? */ + act = gaim_blist_node_action_new(_("Unsubscribe"), + jabber_buddy_unsubscribe, NULL); + m = g_list_append(m, act); } return m; } + +GList * +jabber_blist_node_menu(GaimBlistNode *node) +{ + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return jabber_buddy_menu((GaimBuddy *) node); + } else { + return NULL; + } +} + + diff -r 697e169dac12 -r 7ab20f829190 src/protocols/jabber/buddy.h --- a/src/protocols/jabber/buddy.h Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/jabber/buddy.h Sun May 23 17:27:45 2004 +0000 @@ -66,7 +66,7 @@ void jabber_buddy_get_info_chat(GaimConnection *gc, int id, const char *resource); -GList *jabber_buddy_menu(GaimConnection *gc, const char *name); +GList *jabber_blist_node_menu(GaimBlistNode *node); void jabber_set_info(GaimConnection *gc, const char *info); void jabber_setup_set_info(GaimPluginAction *action); diff -r 697e169dac12 -r 7ab20f829190 src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/jabber/jabber.c Sun May 23 17:27:45 2004 +0000 @@ -22,9 +22,9 @@ #include "account.h" #include "accountopt.h" +#include "blist.h" #include "debug.h" #include "message.h" -#include "multi.h" #include "notify.h" #include "pluginpref.h" #include "prpl.h" @@ -1297,7 +1297,7 @@ jabber_status_text, jabber_tooltip_text, jabber_away_states, - jabber_buddy_menu, + jabber_blist_node_menu, jabber_chat_info, jabber_login, jabber_close, @@ -1341,7 +1341,6 @@ jabber_find_blist_chat, jabber_roomlist_get_list, jabber_roomlist_cancel, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/jabber/si.c --- a/src/protocols/jabber/si.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/jabber/si.c Sun May 23 17:27:45 2004 +0000 @@ -18,6 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + +#include "blist.h" + #include "internal.h" #include "debug.h" #include "ft.h" @@ -641,16 +644,25 @@ } } -void jabber_si_xfer_ask_send(GaimConnection *gc, const char *name) +void jabber_si_xfer_ask_send(GaimBlistNode *node, gpointer data) { - JabberStream *js = gc->proto_data; + GaimBuddy *buddy; + GaimConnection *gc; + JabberStream *js; + GaimXfer *xfer; JabberSIXfer *jsx; - if(!gaim_find_buddy(gc->account, name) || !jabber_buddy_find(js, name, FALSE)) + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + js = gc->proto_data; + + if(!gaim_find_buddy(gc->account, buddy->name) || !jabber_buddy_find(js, buddy->name, FALSE)) return; - xfer = gaim_xfer_new(gaim_connection_get_account(gc), GAIM_XFER_SEND, name); + xfer = gaim_xfer_new(buddy->account, GAIM_XFER_SEND, buddy->name); xfer->data = jsx = g_new0(JabberSIXfer, 1); jsx->js = js; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/jabber/si.h --- a/src/protocols/jabber/si.h Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/jabber/si.h Sun May 23 17:27:45 2004 +0000 @@ -28,6 +28,6 @@ void jabber_bytestreams_parse(JabberStream *js, xmlnode *packet); void jabber_si_parse(JabberStream *js, xmlnode *packet); -void jabber_si_xfer_ask_send(GaimConnection *gc, const char *name); +void jabber_si_xfer_ask_send(GaimBlistNode *node, gpointer data); #endif /* _GAIM_JABBER_SI_H_ */ diff -r 697e169dac12 -r 7ab20f829190 src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/msn/msn.c Sun May 23 17:27:45 2004 +0000 @@ -20,7 +20,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include "internal.h" +#include "blist.h" #include "msn.h" #include "accountopt.h" #include "msg.h" @@ -30,7 +32,6 @@ #include "session.h" #include "state.h" #include "utils.h" -#include "multi.h" #include "util.h" #include "notification.h" @@ -234,53 +235,67 @@ { GaimConnection *gc = (GaimConnection *) action->context; gaim_request_action(gc, NULL, _("Allow MSN Mobile pages?"), - _("Do you want to allow or disallow people on " - "your buddy list to send you MSN Mobile pages " - "to your cell phone or other mobile device?"), - -1, gc, 3, - _("Allow"), G_CALLBACK(enable_msn_pages_cb), - _("Disallow"), G_CALLBACK(disable_msn_pages_cb), - _("Cancel"), NULL); + _("Do you want to allow or disallow people on " + "your buddy list to send you MSN Mobile pages " + "to your cell phone or other mobile device?"), + -1, gc, 3, + _("Allow"), G_CALLBACK(enable_msn_pages_cb), + _("Disallow"), G_CALLBACK(disable_msn_pages_cb), + _("Cancel"), NULL); } static void -show_send_to_mobile_cb(GaimConnection *gc, const char *passport) +show_send_to_mobile_cb(GaimBlistNode *node, gpointer ignored) { + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + MsnUser *user; MsnSession *session; MsnMobileData *data; session = gc->proto_data; - user = msn_users_find_with_passport(session->users, passport); + user = msn_users_find_with_passport(session->users, buddy->name); data = g_new0(MsnMobileData, 1); data->gc = gc; - data->passport = passport; + data->passport = buddy->name; gaim_request_input(gc, NULL, _("Send a mobile message."), NULL, - NULL, TRUE, FALSE, NULL, - _("Page"), G_CALLBACK(send_to_mobile_cb), - _("Close"), G_CALLBACK(close_mobile_page_cb), - data); + NULL, TRUE, FALSE, NULL, + _("Page"), G_CALLBACK(send_to_mobile_cb), + _("Close"), G_CALLBACK(close_mobile_page_cb), + data); } static void -initiate_chat_cb(GaimConnection *gc, const char *passport) +initiate_chat_cb(GaimBlistNode *node, gpointer data) { - GaimAccount *account; + GaimBuddy *buddy; + GaimConnection *gc; + MsnSession *session; MsnCmdProc *cmdproc; MsnSwitchBoard *swboard; MsnUser *user; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - account = gaim_connection_get_account(gc); + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + session = gc->proto_data; cmdproc = session->notification_conn->cmdproc; if ((swboard = msn_session_open_switchboard(session)) == NULL) return; - user = msn_user_new(session, passport, NULL); + user = msn_user_new(session, buddy->name, NULL); msn_switchboard_set_user(swboard, user); @@ -291,7 +306,7 @@ swboard->chat = serv_got_joined_chat(gc, swboard->chat_id, "MSN Chat"); gaim_conv_chat_add_user(GAIM_CONV_CHAT(swboard->chat), - gaim_account_get_username(account), NULL); + gaim_account_get_username(buddy->account), NULL); } /************************************************************************** @@ -410,45 +425,46 @@ } static GList * -msn_buddy_menu(GaimConnection *gc, const char *who) +msn_buddy_menu(GaimBuddy *buddy) { - GaimAccount *account; MsnUser *user; - struct proto_buddy_menu *pbm; - GaimBuddy *b; - GList *m = NULL; - account = gaim_connection_get_account(gc); - b = gaim_find_buddy(account, who); + GList *m = NULL; + GaimBlistNodeAction *act; - g_return_val_if_fail(b != NULL, NULL); - - user = b->proto_data; - + user = buddy->proto_data; if (user != NULL) { if (user->mobile) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send to Mobile"); - pbm->callback = show_send_to_mobile_cb; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Send to Mobile"), + show_send_to_mobile_cb, NULL); + m = g_list_append(m, act); } } - if (g_ascii_strcasecmp(who, gaim_account_get_username(account))) + if (g_ascii_strcasecmp(buddy->name, gaim_account_get_username(buddy->account))) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Initiate Chat"); - pbm->callback = initiate_chat_cb; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Initiate Chat"), + initiate_chat_cb, NULL); + m = g_list_append(m, act); } return m; } + +static GList * +msn_blist_node_menu(GaimBlistNode *node) +{ + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return msn_buddy_menu((GaimBuddy *) node); + } else { + return NULL; + } +} + + static void msn_login(GaimAccount *account) { @@ -1626,7 +1642,7 @@ msn_status_text, msn_tooltip_text, msn_away_states, - msn_buddy_menu, + msn_blist_node_menu, NULL, msn_login, msn_close, @@ -1670,7 +1686,6 @@ NULL, NULL, NULL, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/napster/napster.c --- a/src/protocols/napster/napster.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/napster/napster.c Sun May 23 17:27:45 2004 +0000 @@ -21,6 +21,7 @@ #include "account.h" #include "accountopt.h" +#include "blist.h" #include "conversation.h" #include "debug.h" #include "multi.h" @@ -532,20 +533,6 @@ *se = "offline"; } -static GList *nap_buddy_menu(GaimConnection *gc, const char *who) -{ - GList *m = NULL; - struct proto_buddy_menu *pbm; - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Get Info"); - pbm->callback = nap_get_info; - pbm->gc = gc; - m = g_list_append(m, pbm); - - return m; -} - static GList *nap_chat_info(GaimConnection *gc) { GList *m = NULL; @@ -572,7 +559,7 @@ NULL, NULL, NULL, - nap_buddy_menu, + NULL, nap_chat_info, nap_login, nap_close, @@ -616,7 +603,6 @@ NULL, NULL, NULL, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/novell/novell.c --- a/src/protocols/novell/novell.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/novell/novell.c Sun May 23 17:27:45 2004 +0000 @@ -1519,20 +1519,28 @@ } static void -_initiate_conference_cb(GaimConnection *gc, const char *who) +_initiate_conference_cb(GaimBlistNode *node, gpointer ignored) { + GaimBuddy *buddy; + GaimConnection *gc; + NMUser *user; const char *conf_name; GaimConversation *chat = NULL; NMUserRecord *user_record; NMConference *conference; + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + user = gc->proto_data; if (user == NULL) return; /* We should already have a userrecord for the buddy */ - user_record = nm_find_user_record(user, who); + user_record = nm_find_user_record(user, buddy->name); if (user_record == NULL) return; @@ -3274,16 +3282,16 @@ } static GList * -novell_buddy_menu(GaimConnection *gc, const char *who) +novell_blist_node_menu(GaimBlistNode *node) { GList *list = NULL; - struct proto_buddy_menu *pbm; - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Initiate _Chat"); - pbm->callback = _initiate_conference_cb; - pbm->gc = gc; - list = g_list_append(list, pbm); + GaimBlistNodeAction *act; + + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + act = gaim_blist_node_action_new(_("Initiate _Chat"), + _initiate_conference_cb, NULL); + list = g_list_append(list, act); + } return list; } @@ -3298,7 +3306,7 @@ novell_status_text, novell_tooltip_text, novell_away_states, - novell_buddy_menu, + novell_blist_node_menu, NULL, /* chat_info */ novell_login, novell_close, @@ -3337,6 +3345,11 @@ NULL, /* normalize */ NULL, /* set_buddy_icon */ novell_remove_group, + NULL, + NULL, + NULL, + NULL, + NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/oscar/oscar.c Sun May 23 17:27:45 2004 +0000 @@ -1344,20 +1344,31 @@ } /* this is the right click menu cb thingy */ -static void oscar_ask_direct_im(GaimConnection *gc, const char *who) { +static void oscar_ask_direct_im(GaimBlistNode *node, gpointer ignored) { + + GaimBuddy *buddy; + GaimConnection *gc; gchar *buf; - struct ask_do_dir_im *data = g_new0(struct ask_do_dir_im, 1); - data->who = g_strdup(who); + struct ask_do_dir_im *data; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + + data = g_new0(struct ask_do_dir_im, 1); + data->who = g_strdup(buddy->name); data->gc = gc; - buf = g_strdup_printf(_("You have selected to open a Direct IM connection with %s."), who); + buf = g_strdup_printf(_("You have selected to open a Direct IM connection with %s."), + buddy->name); gaim_request_action(gc, NULL, buf, - _("Because this reveals your IP address, it " - "may be considered a privacy risk. Do you " - "wish to continue?"), - 0, data, 2, - _("Connect"), G_CALLBACK(oscar_direct_im), - _("Cancel"), G_CALLBACK(oscar_cancel_direct_im)); + _("Because this reveals your IP address, it " + "may be considered a privacy risk. Do you " + "wish to continue?"), + 0, data, 2, + _("Connect"), G_CALLBACK(oscar_direct_im), + _("Cancel"), G_CALLBACK(oscar_cancel_direct_im)); g_free(buf); } @@ -1908,20 +1919,30 @@ } } -static void oscar_ask_sendfile(GaimConnection *gc, const char *destsn) { - OscarData *od = (OscarData *)gc->proto_data; +static void oscar_ask_sendfile(GaimBlistNode *node, gpointer data) { + + GaimBuddy *buddy; + GaimConnection *gc; + + OscarData *od; GaimXfer *xfer; struct aim_oft_info *oft_info; const char *ip; + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + od = (OscarData *)gc->proto_data; + /* You want to send a file to someone else, you're so generous */ /* Build the file transfer handle */ - xfer = gaim_xfer_new(gaim_connection_get_account(gc), GAIM_XFER_SEND, destsn); + xfer = gaim_xfer_new(buddy->account, GAIM_XFER_SEND, buddy->name); /* Create the oscar-specific data */ ip = gaim_network_get_my_ip(od->conn ? od->conn->fd : -1); - oft_info = aim_oft_createinfo(od->sess, NULL, destsn, ip, 0, 0, 0, NULL); + oft_info = aim_oft_createinfo(od->sess, NULL, buddy->name, ip, 0, 0, 0, NULL); xfer->data = oft_info; /* Setup our I/O op functions */ @@ -3324,7 +3345,8 @@ oscar_free_name_data(data); } -static void gaim_auth_sendrequest(GaimConnection *gc, const char *name) { + +static void gaim_auth_sendrequest(GaimConnection *gc, char *name) { struct name_data *data = g_new(struct name_data, 1); GaimBuddy *buddy; gchar *dialog_msg, *nombre; @@ -3350,6 +3372,18 @@ g_free(nombre); } + +static void gaim_auth_sendrequest_menu(GaimBlistNode *node, gpointer ignored) { + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + gaim_auth_sendrequest(gc, buddy->name); +} + /* When other people ask you for authorization */ static void gaim_auth_grant(struct name_data *data) { GaimConnection *gc = data->gc; @@ -5068,7 +5102,7 @@ } return 0; } -static void oscar_ask_direct_im(GaimConnection *gc, const char *name); + static int gaim_odc_send_im(aim_session_t *, aim_conn_t *, const char *, GaimConvImFlags); static int oscar_send_im(GaimConnection *gc, const char *name, const char *message, GaimConvImFlags imflags) { @@ -6624,23 +6658,31 @@ oscar_free_name_data(data); } -static void oscar_buddycb_edit_comment(GaimConnection *gc, const char *name) { - OscarData *od = gc->proto_data; - struct name_data *data = g_new(struct name_data, 1); - GaimBuddy *b; +static void oscar_buddycb_edit_comment(GaimBlistNode *node, gpointer ignore) { + + GaimBuddy *buddy; + GaimConnection *gc; + OscarData *od; + struct name_data *data; GaimGroup *g; char *comment; gchar *comment_utf8; - if (!(b = gaim_find_buddy(gaim_connection_get_account(gc), name))) + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + od = gc->proto_data; + + data = g_new(struct name_data, 1); + + if (!(g = gaim_find_buddys_group(buddy))) return; - if (!(g = gaim_find_buddys_group(b))) - return; - comment = aim_ssi_getcomment(od->sess->ssi.local, g->name, name); + comment = aim_ssi_getcomment(od->sess->ssi.local, g->name, buddy->name); comment_utf8 = comment ? gaim_utf8_try_convert(comment) : NULL; data->gc = gc; - data->name = g_strdup(name); + data->name = g_strdup(buddy->name); data->nick = NULL; gaim_request_input(gc, NULL, _("Buddy Comment:"), NULL, @@ -6653,74 +6695,74 @@ g_free(comment_utf8); } -static GList *oscar_buddy_menu(GaimConnection *gc, const char *who) { +static GList *oscar_buddy_menu(GaimBuddy *buddy) { + + GaimConnection *gc = gaim_account_get_connection(buddy->account); OscarData *od = gc->proto_data; + GList *m = NULL; - struct proto_buddy_menu *pbm; - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Edit Buddy Comment"); - pbm->callback = oscar_buddycb_edit_comment; - pbm->gc = gc; - m = g_list_append(m, pbm); + GaimBlistNodeAction *act; + + act = gaim_blist_node_action_new(_("Edit Buddy Comment"), + oscar_buddycb_edit_comment, NULL); + m = g_list_append(m, act); if (od->icq) { #if 0 - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Get Status Msg"); - pbm->callback = oscar_get_icqstatusmsg; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Get Status Msg"), + oscar_get_icqstatusmsg, NULL); + m = g_list_append(m, act); #endif } else { - GaimBuddy *b = gaim_find_buddy(gc->account, who); aim_userinfo_t *userinfo; - - if (b) - userinfo = aim_locate_finduserinfo(od->sess, b->name); - - if (b && userinfo && aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) { + userinfo = aim_locate_finduserinfo(od->sess, buddy->name); + + if (userinfo && aim_sncmp(gaim_account_get_username(buddy->account), buddy->name) && + GAIM_BUDDY_IS_ONLINE(buddy)) { + if (userinfo->capabilities & AIM_CAPS_DIRECTIM) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Direct IM"); - pbm->callback = oscar_ask_direct_im; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Direct IM"), + oscar_ask_direct_im, NULL); + m = g_list_append(m, act); } if (userinfo->capabilities & AIM_CAPS_SENDFILE) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send File"); - pbm->callback = oscar_ask_sendfile; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Send File"), + oscar_ask_sendfile, NULL); + m = g_list_append(m, act); } #if 0 if (userinfo->capabilities & AIM_CAPS_GETFILE) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Get File"); - pbm->callback = oscar_ask_getfile; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Get File"), + oscar_ask_getfile, NULL); + m = g_list_append(m, act); } #endif } } if (od->sess->ssi.received_data) { - char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, who); - if (gname && aim_ssi_waitingforauth(od->sess->ssi.local, gname, who)) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Re-request Authorization"); - pbm->callback = gaim_auth_sendrequest; - pbm->gc = gc; - m = g_list_append(m, pbm); + char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, buddy->name); + if (gname && aim_ssi_waitingforauth(od->sess->ssi.local, gname, buddy->name)) { + act = gaim_blist_node_action_new(_("Re-request Authorization"), + gaim_auth_sendrequest_menu, NULL); + m = g_list_append(m, act); } } return m; } + +static GList *oscar_blist_node_menu(GaimBlistNode *node) { + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return oscar_buddy_menu((GaimBuddy *) node); + } else { + return NULL; + } +} + + static void oscar_format_screenname(GaimConnection *gc, const char *nick) { OscarData *od = gc->proto_data; if (!aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), nick)) { @@ -7072,7 +7114,7 @@ oscar_status_text, oscar_tooltip_text, oscar_away_states, - oscar_buddy_menu, + oscar_blist_node_menu, oscar_chat_info, oscar_login, oscar_close, @@ -7122,7 +7164,6 @@ NULL, NULL, NULL, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/silc/buddy.c --- a/src/protocols/silc/buddy.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/silc/buddy.c Sun May 23 17:27:45 2004 +0000 @@ -314,21 +314,27 @@ /**************************** Static IM Key **********************************/ static void -silcgaim_buddy_resetkey(GaimConnection *gc, const char *name) +silcgaim_buddy_resetkey(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimBuddy *b; + GaimConnection *gc; + SilcGaim sg; char *nickname; SilcClientEntry *clients; SilcUInt32 clients_count; - if (!name) - return; - if (!silc_parse_userfqdn(name, &nickname, NULL)) + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + sg = gc->proto_data; + + if (!silc_parse_userfqdn(b->name, &nickname, NULL)) return; /* Find client entry */ clients = silc_client_get_clients_local(sg->client, sg->conn, - nickname, name, + nickname, b->name, &clients_count); if (!clients) { silc_free(nickname); @@ -411,27 +417,33 @@ } static void -silcgaim_buddy_privkey(GaimConnection *gc, const char *name) +silcgaim_buddy_privkey(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimBuddy *b; + GaimConnection *gc; + SilcGaim sg; char *nickname; SilcGaimPrivkey p; SilcClientEntry *clients; SilcUInt32 clients_count; - if (!name) - return; - if (!silc_parse_userfqdn(name, &nickname, NULL)) + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + sg = gc->proto_data; + + if (!silc_parse_userfqdn(b->name, &nickname, NULL)) return; /* Find client entry */ clients = silc_client_get_clients_local(sg->client, sg->conn, - nickname, name, + nickname, b->name, &clients_count); if (!clients) { silc_client_get_clients(sg->client, sg->conn, nickname, NULL, silcgaim_buddy_privkey_resolved, - g_strdup(name)); + g_strdup(b->name)); silc_free(nickname); return; } @@ -522,29 +534,36 @@ } static void -silcgaim_buddy_getkey(GaimConnection *gc, const char *name) +silcgaim_buddy_getkey(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; + GaimBuddy *b; + GaimConnection *gc; + SilcGaim sg; + SilcClient client; + SilcClientConnection; SilcClientEntry *clients; SilcUInt32 clients_count; SilcGaimBuddyGetkey g; char *nickname; - if (!name) - return; + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - if (!silc_parse_userfqdn(name, &nickname, NULL)) + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + sg = gc->proto_data; + client = sg->client; + conn = sg->conn; + + if (!silc_parse_userfqdn(b->name, &nickname, NULL)) return; /* Find client entry */ - clients = silc_client_get_clients_local(client, conn, nickname, name, - &clients_count); + clients = silc_client_get_clients_local(client, conn, nickname, + b->name, &clients_count); if (!clients) { silc_client_get_clients(client, conn, nickname, NULL, silcgaim_buddy_getkey_resolved, - g_strdup(name)); + g_strdup(b->name)); silc_free(nickname); return; } @@ -566,18 +585,21 @@ } static void -silcgaim_buddy_showkey(GaimConnection *gc, const char *name) +silcgaim_buddy_showkey(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimBuddy *b; + GaimConnection *gc; + SilcGaim sg; SilcPublicKey public_key; const char *pkfile; - GaimBuddy *b; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); - b = gaim_find_buddy(gc->account, name); - if (!b) - return; + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + sg = gc->proto_data; - pkfile = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); + pkfile = gaim_blist_node_get_string(buddy, "public-key"); if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) && !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) { gaim_notify_error(gc, @@ -586,7 +608,7 @@ return; } - silcgaim_show_public_key(sg, name, public_key, NULL, NULL); + silcgaim_show_public_key(sg, b->name, public_key, NULL, NULL); silc_pkcs_public_key_free(public_key); } @@ -1536,87 +1558,87 @@ } static void -silcgaim_buddy_kill(GaimConnection *gc, const char *name) +silcgaim_buddy_kill(GaimBlistNode *buddy, gpointer data) { - SilcGaim sg = gc->proto_data; - SilcClient client = sg->client; - SilcClientConnection conn = sg->conn; + GaimBuddy *b; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + sg = gc->proto_data; /* Call KILL */ - silc_client_command_call(client, conn, NULL, "KILL", - name, "Killed by operator", NULL); + silc_client_command_call(sg->client, sg->conn, NULL, "KILL", + b->name, "Killed by operator", NULL); } static void -silcgaim_buddy_send_file(GaimConnection *gc, const char *name) +silcgaim_buddy_send_file(GaimBlistNode *buddy, gpointer data) { - silcgaim_ftp_send_file(gc, name); + GaimBuddy *b; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + b = (GaimBuddy *) node; + gc = gaim_account_get_connection(b->account); + + silcgaim_ftp_send_file(gc, b->name); } -GList *silcgaim_buddy_menu(GaimConnection *gc, const char *name) +GList *silcgaim_buddy_menu(GaimBuddy *buddy) { + + GaimConnection *gc = gaim_account_get_connection(buddy->account); SilcGaim sg = gc->proto_data; SilcClientConnection conn = sg->conn; - GList *m = NULL; - struct proto_buddy_menu *pbm; - GaimBuddy *b; const char *pkfile = NULL; SilcClientEntry client_entry = NULL; + GaimBlistNodeAction *act; + GList *m = NULL; - b = gaim_find_buddy(gc->account, name); - if (b) { - pkfile = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); - client_entry = silc_client_get_client_by_id(sg->client, - sg->conn, - b->proto_data); - } + pkfile = gaim_blist_node_get_string(node, "public-key"); + client_entry = silc_client_get_client_by_id(sg->client, + sg->conn, + b->proto_data); if (client_entry && client_entry->send_key) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Reset IM Key"); - pbm->callback = silcgaim_buddy_resetkey; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Reset IM Key"), + silcgaim_buddy_resetkey); + m = g_list_append(m, act); + } else { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("IM with Key Exchange"); - pbm->callback = silcgaim_buddy_keyagr; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("IM with Key Exchange"), + silcgaim_buddy_keyagr); + m = g_list_append(m, act); - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("IM with Password"); - pbm->callback = silcgaim_buddy_privkey; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("IM with Password"), + silcgaim_buddy_privkey); + m = g_list_append(m, act); } if (pkfile) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Show Public Key"); - pbm->callback = silcgaim_buddy_showkey; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Show Public Key"), + silcgaim_buddy_showkey); + m = g_list_append(m, act); + } else { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Get Public Key..."); - pbm->callback = silcgaim_buddy_getkey; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Get Public Key..."), + silcgaim_buddy_getkey); + m = g_list_append(m, act); } - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send File..."); - pbm->callback = silcgaim_buddy_send_file; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Send File..."), + silcgaim_buddy_send_file); + m = g_list_append(m, act); if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Kill User"); - pbm->callback = silcgaim_buddy_kill; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Kill User"), + silcgaim_buddy_kill); + m = g_list_append(m, act); } return m; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/silc/chat.c --- a/src/protocols/silc/chat.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/silc/chat.c Sun May 23 17:27:45 2004 +0000 @@ -43,7 +43,7 @@ } static void -silcgaim_chat_getinfo(GaimConnection *gc, GHashTable *components); +silcgaim_chat_getinfo(GaimBlistNode *node, gpointer data); static void silcgaim_chat_getinfo_res(SilcClient client, @@ -73,9 +73,12 @@ } static void -silcgaim_chat_getinfo(GaimConnection *gc, GHashTable *components) +silcgaim_chat_getinfo(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + const char *chname; char *buf, tmp[256]; GString *s; @@ -83,10 +86,13 @@ SilcHashTableList htl; SilcChannelUser chu; - if (!components) - return; + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); - chname = g_hash_table_lookup(components, "channel"); + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + + chname = g_hash_table_lookup(chat->components, "channel"); if (!chname) return; channel = silc_client_get_channel(sg->client, sg->conn, @@ -95,7 +101,7 @@ silc_client_get_channel_resolve(sg->client, sg->conn, (char *)chname, silcgaim_chat_getinfo_res, - components); + chat->components); return; } @@ -162,7 +168,7 @@ /************************** Channel Invite List ******************************/ static void -silcgaim_chat_invitelist(GaimConnection *gc, GHashTable *components) +silcgaim_chat_invitelist(GaimBlistNode *node, gpointer data); { } @@ -171,7 +177,7 @@ /**************************** Channel Ban List *******************************/ static void -silcgaim_chat_banlist(GaimConnection *gc, GHashTable *components) +silcgaim_chat_banlist(GaimBlistNode *node, gpointer data); { } @@ -440,11 +446,20 @@ } static void -silcgaim_chat_chauth(GaimConnection *gc, GHashTable *components) +silcgaim_chat_chauth(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "+C", NULL); } @@ -513,21 +528,30 @@ } static void -silcgaim_chat_prv(GaimConnection *gc, GHashTable *components) +silcgaim_chat_prv(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + SilcGaimCharPrv p; GaimRequestFields *fields; GaimRequestFieldGroup *g; GaimRequestField *f; char tmp[512]; + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + p = silc_calloc(1, sizeof(*p)); if (!p) return; p->sg = sg; - p->channel = g_hash_table_lookup(components, "channel"); + p->channel = g_hash_table_lookup(chat->components, "channel"); p->c = gaim_blist_find_chat(sg->account, p->channel); fields = gaim_request_fields_new(); @@ -559,20 +583,37 @@ /****************************** Channel Modes ********************************/ static void -silcgaim_chat_permanent_reset(GaimConnection *gc, GHashTable *components) +silcgaim_chat_permanent_reset(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "-f", NULL); } static void -silcgaim_chat_permanent(GaimConnection *gc, GHashTable *components) +silcgaim_chat_permanent(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; const char *channel; + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + if (!sg->conn) return; @@ -581,7 +622,7 @@ (default key). */ /* Call CMODE */ - channel = g_hash_table_lookup(components, "channel"); + channel = g_hash_table_lookup(chat->components, "channel"); silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", channel, "+f", NULL); } @@ -629,18 +670,27 @@ } static void -silcgaim_chat_ulimit(GaimConnection *gc, GHashTable *components) +silcgaim_chat_ulimit(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + SilcGaimChatInput s; SilcChannelEntry channel; const char *ch; char tmp[32]; + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + if (!sg->conn) return; - ch = g_strdup(g_hash_table_lookup(components, "channel")); + ch = g_strdup(g_hash_table_lookup(chat->components, "channel")); channel = silc_client_get_channel(sg->client, sg->conn, (char *)ch); if (!channel) return; @@ -659,70 +709,127 @@ } static void -silcgaim_chat_resettopic(GaimConnection *gc, GHashTable *components) +silcgaim_chat_resettopic(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "-t", NULL); } static void -silcgaim_chat_settopic(GaimConnection *gc, GHashTable *components) +silcgaim_chat_settopic(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "+t", NULL); } static void -silcgaim_chat_resetprivate(GaimConnection *gc, GHashTable *components) +silcgaim_chat_resetprivate(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "-p", NULL); } static void -silcgaim_chat_setprivate(GaimConnection *gc, GHashTable *components) +silcgaim_chat_setprivate(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "+p", NULL); } static void -silcgaim_chat_resetsecret(GaimConnection *gc, GHashTable *components) +silcgaim_chat_resetsecret(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "-s", NULL); } static void -silcgaim_chat_setsecret(GaimConnection *gc, GHashTable *components) +silcgaim_chat_setsecret(GaimBlistNode *node, gpointer data) { - SilcGaim sg = gc->proto_data; + GaimChat *chat; + GaimConnection *gc; + SilcGaim sg; + + g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); + + chat = (GaimChat *) node; + gc = gaim_account_get_connection(chat->account); + sg = gc->proto_data; + silc_client_command_call(sg->client, sg->conn, NULL, "CMODE", - g_hash_table_lookup(components, "channel"), + g_hash_table_lookup(chat->components, "channel"), "+s", NULL); } -GList *silcgaim_chat_menu(GaimConnection *gc, GHashTable *components) +GList *silcgaim_chat_menu(GaimChat *chat) { + GHashTable components = chat->components; + GaimConnection *gc = gaim_account_get_connection(chat->account); SilcGaim sg = gc->proto_data; SilcClientConnection conn = sg->conn; - GList *m = NULL; - struct proto_chat_menu *pcm; const char *chname = NULL; SilcChannelEntry channel = NULL; SilcChannelUser chu = NULL; SilcUInt32 mode = 0; + GList *m; + GaimBlistNodeAction *act; + if (components) chname = g_hash_table_lookup(components, "channel"); if (chname) @@ -737,106 +844,78 @@ if (strstr(chname, "[Private Group]")) return NULL; - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Get Info"); - pcm->callback = silcgaim_chat_getinfo; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Get Info"), + silcgaim_chat_getinfo, NULL); + m = g_list_append(m, act); #if 0 /* XXX For now these are not implemented. We need better listview dialog from Gaim for these. */ if (mode & SILC_CHANNEL_UMODE_CHANOP) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Invite List"); - pcm->callback = silcgaim_chat_invitelist; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Invite List"), + silcgaim_chat_invitelist, NULL); + m = g_list_append(m, act); - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Ban List"); - pcm->callback = silcgaim_chat_banlist; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Ban List"), + silcgaim_chat_banlist, NULL); + m = g_list_append(m, act); } #endif if (chu) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Add Private Group"); - pcm->callback = silcgaim_chat_prv; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Add Private Group"), + silcgaim_chat_prv, NULL); + m = g_list_append(m, act); } if (mode & SILC_CHANNEL_UMODE_CHANFO) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Channel Authentication"); - pcm->callback = silcgaim_chat_chauth; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Channel Authentication"), + silcgaim_chat_chauth, NULL); + m = g_list_append(m, act); if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Reset Permanent"); - pcm->callback = silcgaim_chat_permanent_reset; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Reset Permanent"), + silcgaim_chat_permanent_reset, NULL); + m = g_list_append(m, act); } else { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Set Permanent"); - pcm->callback = silcgaim_chat_permanent; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Set Permanent"), + silcgaim_chat_permanent, NULL); + m = g_list_append(m, act); } } if (mode & SILC_CHANNEL_UMODE_CHANOP) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Set User Limit"); - pcm->callback = silcgaim_chat_ulimit; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Set User Limit"), + silcgaim_chat_ulimit, NULL); + m = g_list_append(m, act); if (channel->mode & SILC_CHANNEL_MODE_TOPIC) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Reset Topic Restriction"); - pcm->callback = silcgaim_chat_resettopic; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Reset Topic Restriction"), + silcgaim_chat_resettopic, NULL); + m = g_list_append(m, act); } else { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Set Topic Restriction"); - pcm->callback = silcgaim_chat_settopic; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Set Topic Restriction"), + silcgaim_chat_settopic, NULL); + m = g_list_append(m, act); } if (channel->mode & SILC_CHANNEL_MODE_PRIVATE) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Reset Private Channel"); - pcm->callback = silcgaim_chat_resetprivate; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Reset Private Channel"), + silcgaim_chat_resetprivate, NULL); + m = g_list_append(m, act); } else { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Set Private Channel"); - pcm->callback = silcgaim_chat_setprivate; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Set Private Channel"), + silcgaim_chat_setprivate, NULL); + m = g_list_append(m, act); } if (channel->mode & SILC_CHANNEL_MODE_SECRET) { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Reset Secret Channel"); - pcm->callback = silcgaim_chat_resetsecret; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Reset Secret Channel"), + silcgaim_chat_resetsecret, NULL); + m = g_list_append(m, act); } else { - pcm = g_new0(struct proto_chat_menu, 1); - pcm->label = _("Set Secret Channel"); - pcm->callback = silcgaim_chat_setsecret; - pcm->gc = gc; - m = g_list_append(m, pcm); + act = gaim_blist_node_action_new(_("Set Secret Channel"), + silcgaim_chat_setsecret, NULL); + m = g_list_append(m, act); } } diff -r 697e169dac12 -r 7ab20f829190 src/protocols/silc/silc.c --- a/src/protocols/silc/silc.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/silc/silc.c Sun May 23 17:27:45 2004 +0000 @@ -880,6 +880,20 @@ } +GList *silcgaim_blist_node_menu(GaimBlistNode *node) { + /* split this single menu building function back into the two + original: one for buddies and one for chats */ + + if(GAIM_BLIST_NODE_IS_CHAT(node)) { + return silcgaim_chat_menu((GaimChar *) node); + } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return silcgaim_buddy_menu((GaimBuddy *) node); + } else { + return_val_if_reached(NULL); + } +} + + /************************** Plugin Initialization ****************************/ static GaimPluginPrefFrame * @@ -949,7 +963,7 @@ silcgaim_status_text, silcgaim_tooltip_text, silcgaim_away_states, - silcgaim_buddy_menu, + silcgaim_blist_node_menu, silcgaim_chat_info, silcgaim_login, silcgaim_close, @@ -993,8 +1007,7 @@ NULL, silcgaim_roomlist_get_list, silcgaim_roomlist_cancel, - NULL, - silcgaim_chat_menu + NULL }; static GaimPluginInfo info = diff -r 697e169dac12 -r 7ab20f829190 src/protocols/toc/toc.c --- a/src/protocols/toc/toc.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/toc/toc.c Sun May 23 17:27:45 2004 +0000 @@ -25,7 +25,6 @@ #include "conversation.h" #include "debug.h" #include "prpl.h" -#include "multi.h" #include "notify.h" #include "proxy.h" #include "request.h" @@ -1119,10 +1118,19 @@ } /* Should be implemented as an Account Action? */ -static void toc_get_dir(GaimConnection *gc, const char *name) +static void toc_get_dir(GaimBlistNode *node, gpointer data) { + GaimBuddy *buddy; + GaimConnection *gc; char buf[BUF_LEN * 2]; - g_snprintf(buf, MSG_LEN, "toc_get_dir %s", gaim_normalize(gc->account, name)); + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_acount_get_connection(buddy->account); + + g_snprintf(buf, MSG_LEN, "toc_get_dir %s", + gaim_normalize(buddy->account, buddy->name)); sflap_send(gc, buf, -1, TYPE_DATA); } @@ -1400,16 +1408,16 @@ *ne = emblems[3]; } -static GList *toc_buddy_menu(GaimConnection *gc, const char *who) +static GList *toc_blist_node_menu(GaimBlistNode *node) { GList *m = NULL; - struct proto_buddy_menu *pbm; + GaimBlistNodeAction *act; - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Get Dir Info"); - pbm->callback = toc_get_dir; - pbm->gc = gc; - m = g_list_append(m, pbm); + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + act = gaim_blist_node_action_new(_("Get Dir Info"), + toc_get_dir, NULL); + m = g_list_append(m, act); + } return m; } @@ -2103,7 +2111,7 @@ NULL, NULL, toc_away_states, - toc_buddy_menu, + toc_blist_node_menu, toc_chat_info, toc_login, toc_close, @@ -2147,7 +2155,6 @@ NULL, NULL, NULL, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/protocols/trepia/trepia.c --- a/src/protocols/trepia/trepia.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/trepia/trepia.c Sun May 23 17:27:45 2004 +0000 @@ -34,7 +34,6 @@ /* XXX */ #include "gaim.h" -#include "multi.h" #ifndef _WIN32 # include @@ -444,37 +443,38 @@ } static void -trepia_visit_homepage(GaimConnection *gc, const char *who) +trepia_visit_homepage(GaimBlistNode *node, gpointer data) { + GaimBuddy *buddy; + GaimConnection *gc; TrepiaProfile *profile; - GaimBuddy *b; const char *value; - b = gaim_find_buddy(gaim_connection_get_account(gc), who); + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); profile = b->proto_data; + value = trepia_profile_get_homepage(profile); - if ((value = trepia_profile_get_homepage(profile)) != NULL) + if (value != NULL) gaim_notify_uri(gc, value); } static GList * -trepia_buddy_menu(GaimConnection *gc, const char *who) +trepia_blist_node_menu(GaimBlistNode *node) { - TrepiaProfile *profile; - GaimBuddy *b; - const char *value = NULL; GList *m = NULL; - struct proto_buddy_menu *pbm; + GaimBlistNodeACtion *act; - b = gaim_find_buddy(gaim_connection_get_account(gc), who); - profile = b->proto_data; + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + TrepiaProfile *profile = buddy->proto_data; - if ((value = trepia_profile_get_homepage(profile)) != NULL) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Visit Homepage"); - pbm->callback = trepia_visit_homepage; - pbm->gc = gc; - m = g_list_append(m, pbm); + if (trepia_profile_get_homepage(profile) != NULL) { + act = gaim_blist_node_action_new(_("Visit Homepage"), + trepia_visit_homepage, NULL); + m = g_list_append(m, act); + } } return m; @@ -1214,7 +1214,7 @@ trepia_status_text, trepia_tooltip_text, NULL, - trepia_buddy_menu, + trepia_blist_node_menu, NULL, trepia_login, trepia_close, diff -r 697e169dac12 -r 7ab20f829190 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Sun May 23 17:27:45 2004 +0000 @@ -26,7 +26,6 @@ #include "accountopt.h" #include "blist.h" #include "debug.h" -#include "multi.h" #include "notify.h" #include "privacy.h" #include "prpl.h" @@ -2303,12 +2302,19 @@ } } -static void yahoo_initiate_conference(GaimConnection *gc, const char *name) -{ +static void yahoo_initiate_conference(GaimBlistNode *node, gpointer data) { + + GaimBuddy *buddy; + GaimConnection *gc; + GHashTable *components; struct yahoo_data *yd; int id; + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); yd = gc->proto_data; id = yd->conf_id; @@ -2320,17 +2326,27 @@ yahoo_c_join(gc, components); g_hash_table_destroy(components); - yahoo_c_invite(gc, id, "Join my conference...", name); + yahoo_c_invite(gc, id, "Join my conference...", buddy->name); } -static void yahoo_game(GaimConnection *gc, const char *name) { - struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; +static void yahoo_game(GaimBlistNode *node, gpointer data) { + + GaimBuddy *buddy; + GaimConnection *gc; + + struct yahoo_data *yd; char *game = NULL; char *t; char url[256]; struct yahoo_friend *f; - f = g_hash_table_lookup(yd->friends, name); + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + yd = (struct yahoo_data *) gc->proto_data; + + f = g_hash_table_lookup(yd->friends, buddy->name); if (!f) return; @@ -2414,52 +2430,83 @@ return ret; } -static void yahoo_addbuddyfrommenu_cb(GaimConnection *gc, const char *who) +static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data) +{ + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + + yahoo_add_buddy(gc, buddy->name, NULL); +} + + +static void yahoo_chat_goto_menu(GaimBlistNode *node, gpointer data) { - yahoo_add_buddy(gc, who, NULL); + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + + yahoo_chat_goto(gc, buddy->name); } -static GList *yahoo_buddy_menu(GaimConnection *gc, const char *who) + +static void yahoo_ask_send_file_menu(GaimBlistNode *node, gpointer data) +{ + GaimBuddy *buddy; + GaimConnection *gc; + + g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); + + buddy = (GaimBuddy *) node; + gc = gaim_account_get_connection(buddy->account); + + yahoo_ask_send_file(gc, buddy->name); +} + + +static GList *yahoo_buddy_menu(GaimBuddy *buddy) { GList *m = NULL; - struct proto_buddy_menu *pbm; + GaimBlistNodeAction *act; + + GaimConnection *gc = gaim_account_get_connection(buddy->account); struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; static char buf2[1024]; struct yahoo_friend *f; - f = g_hash_table_lookup(yd->friends, who); + f = g_hash_table_lookup(yd->friends, buddy->name); if (!f) { - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Add Buddy"); - pbm->callback = yahoo_addbuddyfrommenu_cb; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Add Buddy"), + yahoo_addbuddyfrommenu_cb, NULL); + m = g_list_append(m, act); return m; - } - - if (f->status == YAHOO_STATUS_OFFLINE) + + } else if (f->status == YAHOO_STATUS_OFFLINE) { return NULL; - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Join in Chat"); - pbm->callback = yahoo_chat_goto; - pbm->gc = gc; - m = g_list_append(m, pbm); - - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Initiate Conference"); - pbm->callback = yahoo_initiate_conference; - pbm->gc = gc; - m = g_list_append(m, pbm); + } + + act = gaim_blist_node_action_new(_("Join in Chat"), + yahoo_chat_goto_menu, NULL); + m = g_list_append(m, act); + + act = gaim_blist_node_action_new(_("Initiate Conference"), + yahoo_initiate_conference, NULL); + m = g_list_append(m, act); /* FIXME: remove this when the ui does it for us. */ - pbm = g_new0(struct proto_buddy_menu, 1); - pbm->label = _("Send File"); - pbm->callback = yahoo_ask_send_file; - pbm->gc = gc; - m = g_list_append(m, pbm); + act = gaim_blist_node_action_new(_("Send File"), + yahoo_ask_send_file_menu, NULL); + m = g_list_append(m, act); if (f->game) { char *game = f->game; @@ -2469,7 +2516,6 @@ if (!game) return m; - pbm = g_new0(struct proto_buddy_menu, 1); if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ return m; while (*room && *room != '\t') /* skip to the tab */ @@ -2479,15 +2525,25 @@ t++; /* replace the \n with a space */ *t = ' '; g_snprintf(buf2, sizeof buf2, "%s", room); - pbm->label = buf2; - pbm->callback = yahoo_game; - pbm->gc = gc; - m = g_list_append(m, pbm); + + act = gaim_blist_node_action_new(buf2, yahoo_game, NULL); + m = g_list_append(m, act); } return m; } + +static GList *yahoo_blist_node_menu(GaimBlistNode *node) +{ + if(GAIM_BLIST_NODE_IS_BUDDY(node)) { + return yahoo_buddy_menu((GaimBuddy *) node); + } else { + return NULL; + } +} + + static void yahoo_act_id(GaimConnection *gc, const char *entry) { struct yahoo_data *yd = gc->proto_data; @@ -3223,7 +3279,7 @@ yahoo_status_text, yahoo_tooltip_text, yahoo_away_states, - yahoo_buddy_menu, + yahoo_blist_node_menu, yahoo_c_info, yahoo_login, yahoo_close, @@ -3272,8 +3328,7 @@ NULL, yahoo_roomlist_get_list, yahoo_roomlist_cancel, - yahoo_roomlist_expand_category, - NULL + yahoo_roomlist_expand_category }; static GaimPluginInfo info = diff -r 697e169dac12 -r 7ab20f829190 src/protocols/zephyr/zephyr.c --- a/src/protocols/zephyr/zephyr.c Sun May 23 08:06:38 2004 +0000 +++ b/src/protocols/zephyr/zephyr.c Sun May 23 17:27:45 2004 +0000 @@ -1144,30 +1144,14 @@ return buf; } -static void zephyr_zloc(GaimConnection * gc, const char *who) +static void zephyr_zloc(GaimConnection *gc, const char *who) { ZAsyncLocateData_t ald; - if (ZRequestLocations(local_zephyr_normalize(who), &ald, UNACKED, ZAUTH) - != ZERR_NONE) { - return; + if (ZRequestLocations(local_zephyr_normalize(who), &ald, UNACKED, ZAUTH) == ZERR_NONE) { + pending_zloc_names = g_list_append(pending_zloc_names, + g_strdup(local_zephyr_normalize(who))); } - pending_zloc_names = g_list_append(pending_zloc_names, g_strdup(local_zephyr_normalize(who))); -} - -static GList *zephyr_buddy_menu(GaimConnection * gc, const char *who) -{ - GList *m = NULL; - struct proto_buddy_menu *pbm; - - pbm = g_new0(struct proto_buddy_menu, 1); - - pbm->label = _("ZLocate"); - pbm->callback = zephyr_zloc; - pbm->gc = gc; - m = g_list_append(m, pbm); - - return m; } static void zephyr_set_away(GaimConnection * gc, const char *state, const char *msg) @@ -1307,7 +1291,7 @@ NULL, NULL, zephyr_away_states, - zephyr_buddy_menu, + NULL, zephyr_chat_info, zephyr_login, zephyr_close, @@ -1351,7 +1335,6 @@ NULL, NULL, NULL, - NULL, NULL }; diff -r 697e169dac12 -r 7ab20f829190 src/prpl.h --- a/src/prpl.h Sun May 23 08:06:38 2004 +0000 +++ b/src/prpl.h Sun May 23 17:27:45 2004 +0000 @@ -239,7 +239,7 @@ GList *(*away_states)(GaimConnection *gc); - GList *(*buddy_menu)(GaimConnection *, const char *); + GList *(*blist_node_menu)(GaimBlistNode *node); GList *(*chat_info)(GaimConnection *); /* All the server-related functions */ @@ -316,9 +316,6 @@ struct _GaimRoomlist *(*roomlist_get_list)(GaimConnection *gc); void (*roomlist_cancel)(struct _GaimRoomlist *list); void (*roomlist_expand_category)(struct _GaimRoomlist *list, struct _GaimRoomlistRoom *category); - - /* Chat specific menu in the buddy list */ - GList *(*chat_menu)(GaimConnection *, GHashTable *); }; #define GAIM_IS_PROTOCOL_PLUGIN(plugin) \ @@ -327,6 +324,9 @@ #define GAIM_PLUGIN_PROTOCOL_INFO(plugin) \ ((GaimPluginProtocolInfo *)(plugin)->info->extra_info) +/* It's not like we're going to run out of integers for this version + number, but we only want to really change it once per release. */ +/* GAIM_PRPL_API_VERSION last changed for version: 0.78 */ #define GAIM_PRPL_API_VERSION 4 #ifdef __cplusplus diff -r 697e169dac12 -r 7ab20f829190 src/roomlist.h --- a/src/roomlist.h Sun May 23 08:06:38 2004 +0000 +++ b/src/roomlist.h Sun May 23 17:27:45 2004 +0000 @@ -26,6 +26,11 @@ #ifndef _GAIM_ROOMLIST_H_ #define _GAIM_ROOMLIST_H_ + +#include +#include "account.h" + + /**************************************************************************/ /** Data Structures */ /**************************************************************************/