Mercurial > pidgin
changeset 20936:1d8969748cd9
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.
author | Casey Harkins <charkins@pidgin.im> |
---|---|
date | Mon, 15 Oct 2007 01:53:38 +0000 |
parents | 1d9d5de48b9e |
children | 2cf9156f4b85 e0d7429cfd8a |
files | pidgin/gtkdocklet.c |
diffstat | 1 files changed, 118 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- 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)