changeset 13781:743e38a3182b

[gaim-migrate @ 16193] SF Patch #1461027 from Sadrul "This patch: - adds a Conversation->More menu with a list of plugin-actions which now show up in the context-menu for a buddy in the buddy-list. - adds the same actions in the context-menu of the buddies in the chat-list. ... I find this somewhat useful to start a conference or start a doodle-session from the conv. window rather than having to do what from the buddy list." It seems useful to me, but I won't cry if people object and want it removed. If you don't like it, let me know. committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Thu, 18 May 2006 20:53:03 +0000
parents 2096a1549b47
children f4f68315a07a
files src/gtkconv.c src/gtkutils.c
diffstat 2 files changed, 81 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/gtkconv.c	Thu May 18 15:44:02 2006 +0000
+++ b/src/gtkconv.c	Thu May 18 20:53:03 2006 +0000
@@ -1540,6 +1540,7 @@
 	GaimConvChat *chat = GAIM_CONV_CHAT(conv);
 	gboolean is_me = FALSE;
 	GtkWidget *button;
+	GaimBuddy *buddy = NULL;
 
 	if (gc != NULL)
 		prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
@@ -1616,7 +1617,7 @@
 	}
 
 	if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
-		if (gaim_find_buddy(conv->account, who))
+		if ((buddy = gaim_find_buddy(conv->account, who)) != NULL)
 			button = gaim_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE,
 						G_CALLBACK(menu_chat_add_remove_cb), GAIM_GTK_CONVERSATION(conv), 0, 0, NULL);
 		else
@@ -1635,6 +1636,15 @@
 	if (!get_mark_for_user(GAIM_GTK_CONVERSATION(conv), who))
 		gtk_widget_set_sensitive(button, FALSE);
 
+	if (buddy != NULL)
+	{
+		if (gaim_account_is_connected(conv->account))
+			gaim_gtk_append_blist_node_proto_menu(menu, conv->account->gc,
+												  (GaimBlistNode *)buddy);
+		gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy);
+		gtk_widget_show_all(menu);
+	}
+
 	return menu;
 }
 
@@ -2611,6 +2621,7 @@
 			"<StockItem>", GAIM_STOCK_INFO },
 	{ N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0,
 			"<StockItem>", GAIM_STOCK_INVITE },
+	{ N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL },
 
 	{ "/Conversation/sep2", NULL, NULL, 0, "<Separator>", NULL },
 
@@ -2704,12 +2715,67 @@
 	}
 }
 
+static void
+regenerate_options_items(GaimGtkWindow *win)
+{
+	GtkWidget *menu;
+	GList *list;
+	GaimGtkConversation *gtkconv;
+	GaimConversation *conv;
+	GaimBuddy *buddy;
+
+	gtkconv = gaim_gtk_conv_window_get_active_gtkconv(win);
+	conv = gtkconv->active_conv;
+	buddy = gaim_find_buddy(conv->account, conv->name);
+
+	menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Conversation/More"));
+
+	/* Remove the previous entries */
+	for (list = gtk_container_get_children(GTK_CONTAINER(menu)); list; )
+	{
+		GtkWidget *w = list->data;
+		list = list->next;
+		gtk_widget_destroy(w);
+	}
+
+	/* Now add the stuff */
+	if (buddy)
+	{
+		if (gaim_account_is_connected(conv->account))
+			gaim_gtk_append_blist_node_proto_menu(menu, conv->account->gc,
+												  (GaimBlistNode *)buddy);
+		gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy);
+	}
+
+	if ((list = gtk_container_get_children(GTK_CONTAINER(menu))) == NULL)
+	{
+		GtkWidget *item = gtk_menu_item_new_with_label(_("No actions available"));
+		gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+		gtk_widget_set_sensitive(item, FALSE);
+	}
+
+	gtk_widget_show_all(menu);
+}
+
+static void menubar_activated(GtkWidget *item, gpointer data)
+{
+	regenerate_options_items(data);
+	g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data);
+}
+
+static void
+focus_out_from_menubar(GtkWidget *wid, GaimGtkWindow *win)
+{
+	GtkWidget *menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
+	g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), G_CALLBACK(menubar_activated), win);
+}
 
 static GtkWidget *
 setup_menubar(GaimGtkWindow *win)
 {
 	GtkAccelGroup *accel_group;
 	const char *method;
+	GtkWidget *menuitem;
 
 	accel_group = gtk_accel_group_new ();
 	gtk_window_add_accel_group(GTK_WINDOW(win->window), accel_group);
@@ -2727,10 +2793,13 @@
 	g_signal_connect(G_OBJECT(accel_group), "accel-changed",
 	                 G_CALLBACK(gaim_gtk_save_accels_cb), NULL);
 
+	menuitem = gtk_item_factory_get_item(win->menu.item_factory, N_("/Conversation"));
+	g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menubar_activated), win);
 
 	win->menu.menubar =
 		gtk_item_factory_get_widget(win->menu.item_factory, "<main>");
 
+	g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), win);
 
 	win->menu.view_log =
 		gtk_item_factory_get_widget(win->menu.item_factory,
--- a/src/gtkutils.c	Thu May 18 15:44:02 2006 +0000
+++ b/src/gtkutils.c	Thu May 18 20:53:03 2006 +0000
@@ -1687,16 +1687,10 @@
 	if (act == NULL) {
 		gaim_separator(menu);
 	} else {
-		GtkWidget *menuitem, *label;
+		GtkWidget *menuitem;
 
 		if (act->children == NULL) {
-			menuitem = gtk_menu_item_new();
-			label = gtk_label_new("");
-			gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-			gtk_label_set_pattern(GTK_LABEL(label), "_");
-			gtk_label_set_markup_with_mnemonic(GTK_LABEL(label),
-			                                   act->label);
-			gtk_container_add(GTK_CONTAINER(menuitem), label);
+			menuitem = gtk_menu_item_new_with_mnemonic(act->label);
 
 			if (act->callback != NULL) {
 				g_object_set_data(G_OBJECT(menuitem),
@@ -1716,6 +1710,7 @@
 		} 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);
@@ -1723,6 +1718,14 @@
 			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) {
 				GaimMenuAction *act = (GaimMenuAction *)l->data;