changeset 17392:d48026a5f9dd

Use purple_conversation_extended_menu to add items in the conversation window menu. This closes #605.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 25 May 2007 00:36:20 +0000
parents 9c4bd2458677
children 29e68dd7b9cc
files ChangeLog.API pidgin/gtkconv.c pidgin/gtkutils.c pidgin/gtkutils.h
diffstat 4 files changed, 125 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Fri May 25 00:15:33 2007 +0000
+++ b/ChangeLog.API	Fri May 25 00:36:20 2007 +0000
@@ -9,6 +9,7 @@
 
 	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"
--- a/pidgin/gtkconv.c	Fri May 25 00:15:33 2007 +0000
+++ b/pidgin/gtkconv.c	Fri May 25 00:36:20 2007 +0000
@@ -2922,10 +2922,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. */
@@ -4200,10 +4255,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);
 
@@ -4383,6 +4438,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);
 
@@ -7958,6 +8014,7 @@
 
 	generate_send_to_items(win);
 	regenerate_options_items(win);
+	regenerate_plugins_items(win);
 
 	pidgin_conv_switch_active_conversation(conv);
 
@@ -8028,6 +8085,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()
 {
@@ -8102,6 +8165,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);
@@ -8141,6 +8211,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);
 }
--- a/pidgin/gtkutils.c	Fri May 25 00:15:33 2007 +0000
+++ b/pidgin/gtkutils.c	Fri May 25 00:36:20 2007 +0000
@@ -1706,62 +1706,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)
--- a/pidgin/gtkutils.h	Fri May 25 00:15:33 2007 +0000
+++ b/pidgin/gtkutils.h	Fri May 25 00:36:20 2007 +0000
@@ -414,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);
 
 /**