# HG changeset patch # User Casey Harkins # Date 1192413218 0 # Node ID 1d8969748cd9fc3e72b3578df3b937590aadcac1 # Parent 1d9d5de48b9ec4890b1cfab7fa7d351d0d3488d4 Make sure that the "Change Status" submenu in the docklet context menu matches up with the status selector in the buddy list. There is a lot of code duplication introduced here between gtkdocklet.c and gtkstatusbox.c, so I'll probably revist this and see if we should add some API to the statusbox or libpurple level to avoid the duplication. Fixes #2510. diff -r 1d9d5de48b9e -r 1d8969748cd9 pidgin/gtkdocklet.c --- a/pidgin/gtkdocklet.c Mon Oct 15 00:31:34 2007 +0000 +++ b/pidgin/gtkdocklet.c Mon Oct 15 01:53:38 2007 +0000 @@ -38,6 +38,7 @@ #include "gtkprefs.h" #include "gtksavedstatuses.h" #include "gtksound.h" +#include "gtkstatusbox.h" #include "gtkutils.h" #include "pidginstock.h" #include "gtkdocklet.h" @@ -356,6 +357,10 @@ } #endif +/* There is a lot of code here for handling the status submenu, much of + * which is duplicated from the gtkstatusbox. It'd be nice to add API + * somewhere to simplify this (either in the statusbox, or in libpurple). + */ static void show_custom_status_editor_cb(GtkMenuItem *menuitem, gpointer user_data) { @@ -369,6 +374,70 @@ purple_savedstatus_is_transient(saved_status) ? saved_status : NULL); } +static PurpleSavedStatus * +create_transient_status(PurpleStatusPrimitive primitive, PurpleStatusType *status_type) +{ + PurpleSavedStatus *saved_status = purple_savedstatus_new(NULL, primitive); + + if(status_type != NULL) { + GList *tmp, *active_accts = purple_accounts_get_all_active(); + for (tmp = active_accts; tmp != NULL; tmp = tmp->next) { + purple_savedstatus_set_substatus(saved_status, + (PurpleAccount*) tmp->data, status_type, NULL); + } + g_list_free(active_accts); + } + + return saved_status; +} + +static void +activate_status_account_cb(GtkMenuItem *menuitem, gpointer user_data) +{ + PurpleStatusType *status_type; + PurpleStatusPrimitive primitive; + PurpleSavedStatus *saved_status = NULL; + GList *iter = purple_savedstatuses_get_all(); + GList *tmp, *active_accts = purple_accounts_get_all_active(); + + status_type = (PurpleStatusType *)user_data; + primitive = purple_status_type_get_primitive(status_type); + + for (; iter != NULL; iter = iter->next) { + PurpleSavedStatus *ss = iter->data; + if ((purple_savedstatus_get_type(ss) == primitive) && purple_savedstatus_is_transient(ss) && + purple_savedstatus_has_substatuses(ss)) + { + gboolean found = FALSE; + /* The currently enabled accounts must have substatuses for all the active accts */ + for(tmp = active_accts; tmp != NULL; tmp = tmp->next) { + PurpleAccount *acct = tmp->data; + PurpleSavedStatusSub *sub = purple_savedstatus_get_substatus(ss, acct); + if (sub) { + const PurpleStatusType *sub_type = purple_savedstatus_substatus_get_type(sub); + const char *subtype_status_id = purple_status_type_get_id(sub_type); + if (subtype_status_id && !strcmp(subtype_status_id, + purple_status_type_get_id(status_type))) + found = TRUE; + } + } + if (!found) + continue; + saved_status = ss; + break; + } + } + + g_list_free(active_accts); + + /* Create a new transient saved status if we weren't able to find one */ + if (saved_status == NULL) + saved_status = create_transient_status(primitive, status_type); + + /* Set the status for each account */ + purple_savedstatus_activate(saved_status); +} + static void activate_status_primitive_cb(GtkMenuItem *menuitem, gpointer user_data) { @@ -382,7 +451,7 @@ /* Create a new transient saved status if we weren't able to find one */ if (saved_status == NULL) - saved_status = purple_savedstatus_new(NULL, primitive); + saved_status = create_transient_status(primitive, NULL); /* Set the status for each account */ purple_savedstatus_activate(saved_status); @@ -425,31 +494,67 @@ return menuitem; } +static void +add_account_statuses(GtkWidget *menu, PurpleAccount *account) +{ + GList *l; + + for (l = purple_account_get_status_types(account); l != NULL; l = l->next) { + PurpleStatusType *status_type = (PurpleStatusType *)l->data; + PurpleStatusPrimitive prim; + + if (!purple_status_type_is_user_settable(status_type)) + continue; + + prim = purple_status_type_get_primitive(status_type); + + new_menu_item_with_status_icon(menu, + purple_status_type_get_name(status_type), + prim, G_CALLBACK(activate_status_account_cb), + status_type, 0, 0, NULL); + } +} + static GtkWidget * docklet_status_submenu() { GtkWidget *submenu, *menuitem; GList *popular_statuses, *cur; + PidginStatusBox *statusbox = NULL; submenu = gtk_menu_new(); menuitem = gtk_menu_item_new_with_label(_("Change Status")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); - new_menu_item_with_status_icon(submenu, _("Available"), - PURPLE_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb), - GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE), 0, 0, NULL); + if(pidgin_blist_get_default_gtk_blist() != NULL) { + statusbox = PIDGIN_STATUS_BOX(pidgin_blist_get_default_gtk_blist()->statusbox); + } - new_menu_item_with_status_icon(submenu, _("Away"), - PURPLE_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb), - GINT_TO_POINTER(PURPLE_STATUS_AWAY), 0, 0, NULL); + if(statusbox && statusbox->account != NULL) { + add_account_statuses(submenu, statusbox->account); + } else if(statusbox && statusbox->token_status_account != NULL) { + add_account_statuses(submenu, statusbox->token_status_account); + } else { + new_menu_item_with_status_icon(submenu, _("Available"), + PURPLE_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb), + GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE), 0, 0, NULL); - new_menu_item_with_status_icon(submenu, _("Invisible"), - PURPLE_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb), - GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE), 0, 0, NULL); + new_menu_item_with_status_icon(submenu, _("Away"), + PURPLE_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb), + GINT_TO_POINTER(PURPLE_STATUS_AWAY), 0, 0, NULL); + + new_menu_item_with_status_icon(submenu, _("Do not disturb"), + PURPLE_STATUS_UNAVAILABLE, G_CALLBACK(activate_status_primitive_cb), + GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE), 0, 0, NULL); - new_menu_item_with_status_icon(submenu, _("Offline"), - PURPLE_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb), - GINT_TO_POINTER(PURPLE_STATUS_OFFLINE), 0, 0, NULL); + new_menu_item_with_status_icon(submenu, _("Invisible"), + PURPLE_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb), + GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE), 0, 0, NULL); + + new_menu_item_with_status_icon(submenu, _("Offline"), + PURPLE_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb), + GINT_TO_POINTER(PURPLE_STATUS_OFFLINE), 0, 0, NULL); + } popular_statuses = purple_savedstatuses_get_popular(6); if (popular_statuses != NULL)