changeset 14883:c8cd118653fc

[gaim-migrate @ 17652] Add a 'Plugins' item in the buddylist menu (ctrl-o). committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 02 Nov 2006 00:18:34 +0000
parents 62e16ed961cc
children f2b347afd583
files console/gntblist.c console/libgnt/gntmenuitem.c
diffstat 2 files changed, 83 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/console/gntblist.c	Wed Nov 01 21:39:36 2006 +0000
+++ b/console/gntblist.c	Thu Nov 02 00:18:34 2006 +0000
@@ -69,6 +69,11 @@
 	GntWidget *status;          /* Dropdown with the statuses  */
 	GntWidget *statustext;      /* Status message */
 	int typing;
+
+	GntWidget *menu;
+	/* These are the menuitems that get regenerated */
+	GntMenuItem *accounts;
+	GntMenuItem *plugins;
 } GGBlist;
 
 typedef enum
@@ -1766,17 +1771,76 @@
 		action->callback(action);
 }
 
-static GntMenuItem *reconstruct_accounts_menu()
+static void
+build_plugin_actions(GntMenuItem *item, GaimPlugin *plugin, gpointer context)
+{
+	GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP);
+	GList *actions;
+	GntMenuItem *menuitem;
+
+	gnt_menuitem_set_submenu(item, GNT_MENU(sub));
+	for (actions = GAIM_PLUGIN_ACTIONS(plugin, context); actions;
+			actions = g_list_delete_link(actions, actions)) {
+		if (actions->data) {
+			GaimPluginAction *action = actions->data;
+			action->plugin = plugin;
+			action->context = context;
+			menuitem = gnt_menuitem_new(action->label);
+			gnt_menu_add_item(GNT_MENU(sub), menuitem);
+
+			gnt_menuitem_set_callback(menuitem, plugin_action, action);
+			g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
+								   action, (GDestroyNotify)gaim_plugin_action_free);
+		}
+	}
+}
+
+static void
+reconstruct_plugins_menu()
+{
+	GntWidget *sub;
+	GntMenuItem *plg;
+	GList *iter;
+
+	if (!ggblist)
+		return;
+
+	if (ggblist->plugins == NULL)
+		ggblist->plugins = gnt_menuitem_new(_("Plugins"));
+
+	plg = ggblist->plugins;
+	sub = gnt_menu_new(GNT_MENU_POPUP);
+	gnt_menuitem_set_submenu(plg, GNT_MENU(sub));
+
+	for (iter = gaim_plugins_get_loaded(); iter; iter = iter->next) {
+		GaimPlugin *plugin = iter->data;
+		GntMenuItem *item;
+		if (GAIM_IS_PROTOCOL_PLUGIN(plugin))
+			continue;
+
+		if (!GAIM_PLUGIN_HAS_ACTIONS(plugin))
+			continue;
+
+		item = gnt_menuitem_new(_(plugin->info->name));
+		gnt_menu_add_item(GNT_MENU(sub), item);
+		build_plugin_actions(item, plugin, NULL);
+	}
+}
+
+static void
+reconstruct_accounts_menu()
 {
 	GntWidget *sub;
 	GntMenuItem *acc, *item;
 	GList *iter;
 
 	if (!ggblist)
-		return NULL;
+		return;
 
-	acc = gnt_menuitem_new(_("Accounts"));
+	if (ggblist->accounts == NULL)
+		ggblist->accounts = gnt_menuitem_new(_("Accounts"));
 
+	acc = ggblist->accounts;
 	sub = gnt_menu_new(GNT_MENU_POPUP);
 	gnt_menuitem_set_submenu(acc, GNT_MENU(sub));
 
@@ -1791,33 +1855,11 @@
 		prpl = gc->prpl;
 
 		if (GAIM_PLUGIN_HAS_ACTIONS(prpl)) {
-			GList *acts;
-			GntWidget *s;
-
 			item = gnt_menuitem_new(gaim_account_get_username(account));
-			s = gnt_menu_new(GNT_MENU_POPUP);
-			gnt_menuitem_set_submenu(item, GNT_MENU(s));
 			gnt_menu_add_item(GNT_MENU(sub), item);
-
-			for (acts = GAIM_PLUGIN_ACTIONS(prpl, gc); acts;
-					acts = g_list_delete_link(acts, acts)) {
-				GaimPluginAction *action = acts->data;
-				if (!action)
-					continue;
-
-				action->plugin = prpl;
-				action->context = gc;
-
-				item = gnt_menuitem_new(action->label);
-				gnt_menuitem_set_callback(item, plugin_action, action);
-				/* This is to make sure the action is freed when the menu is destroyed */
-				g_object_set_data_full(G_OBJECT(item), "plugin_action", action,
-					(GDestroyNotify)gaim_plugin_action_free);
-				gnt_menu_add_item(GNT_MENU(s), item);
-			}
+			build_plugin_actions(item, prpl, gc);
 		}
 	}
-	return acc;
 }
 
 static void show_offline_cb(GntMenuItem *item, gpointer n)
@@ -1842,7 +1884,7 @@
 		return;
 
 	window = GNT_WINDOW(ggblist->window);
-	menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
+	ggblist->menu = menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
 	gnt_window_set_menu(window, GNT_MENU(menu));
 
 	item = gnt_menuitem_new(_("Options"));
@@ -1867,8 +1909,11 @@
 	gnt_menu_add_item(GNT_MENU(sub), item);
 	gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "log");
 
-	item = reconstruct_accounts_menu();
-	gnt_menu_add_item(GNT_MENU(menu), item);
+	reconstruct_accounts_menu();
+	gnt_menu_add_item(GNT_MENU(menu), ggblist->accounts);
+
+	reconstruct_plugins_menu();
+	gnt_menu_add_item(GNT_MENU(menu), ggblist->plugins);
 }
 
 void gg_blist_show()
@@ -1911,14 +1956,19 @@
 	gnt_widget_show(ggblist->window);
 
 	gaim_signal_connect(gaim_connections_get_handle(), "signed-on", gg_blist_get_handle(),
-				GAIM_CALLBACK(create_menu), NULL);
+				GAIM_CALLBACK(reconstruct_accounts_menu), NULL);
 	gaim_signal_connect(gaim_connections_get_handle(), "signed-off", gg_blist_get_handle(),
-				GAIM_CALLBACK(create_menu), NULL);
+				GAIM_CALLBACK(reconstruct_accounts_menu), NULL);
 	gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(),
 				GAIM_CALLBACK(buddy_status_changed), ggblist);
 	gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(),
 				GAIM_CALLBACK(buddy_idle_changed), ggblist);
 
+	gaim_signal_connect(gaim_plugins_get_handle(), "plugin-load", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_plugins_menu), NULL);
+	gaim_signal_connect(gaim_plugins_get_handle(), "plugin-unload", gg_blist_get_handle(),
+				GAIM_CALLBACK(reconstruct_plugins_menu), NULL);
+
 #if 0
 	gaim_signal_connect(gaim_blist_get_handle(), "buddy-signed-on", gg_blist_get_handle(),
 				GAIM_CALLBACK(buddy_signed_on), ggblist);
--- a/console/libgnt/gntmenuitem.c	Wed Nov 01 21:39:36 2006 +0000
+++ b/console/libgnt/gntmenuitem.c	Thu Nov 02 00:18:34 2006 +0000
@@ -74,6 +74,8 @@
 
 void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu)
 {
+	if (item->submenu)
+		gnt_widget_destroy(item->submenu);
 	item->submenu = menu;
 }