# HG changeset patch # User Evan Schoenberg # Date 1192491972 0 # Node ID 1ec2b67e9bc165245c0885174973a1bcbaceffcf # Parent 37f3c1023a68eee8e0bb4b3d7b84a72fbdf54d86# Parent 2101ebd66f15bdd2a9efcf5651bab1bf7a7f026f merge of '59ab2b78429c94d5d0fc77b1b7892accb524e2a4' and 'e440d3119d6686976d657170c1fce857f4aecfc4' diff -r 37f3c1023a68 -r 1ec2b67e9bc1 finch/libgnt/gntfilesel.c --- a/finch/libgnt/gntfilesel.c Mon Oct 15 23:46:02 2007 +0000 +++ b/finch/libgnt/gntfilesel.c Mon Oct 15 23:46:12 2007 +0000 @@ -265,6 +265,7 @@ } g_free(fp); } + g_dir_close(dir); *files = g_list_reverse(*files); return TRUE; diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/notify.c --- a/libpurple/notify.c Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/notify.c Mon Oct 15 23:46:12 2007 +0000 @@ -688,8 +688,11 @@ void purple_notify_user_info_remove_last_item(PurpleNotifyUserInfo *user_info) { - user_info->user_info_entries = g_list_remove(user_info->user_info_entries, - g_list_last(user_info->user_info_entries)->data); + GList *last = g_list_last(user_info->user_info_entries); + if (last) { + purple_notify_user_info_entry_destroy(last->data); + user_info->user_info_entries = g_list_remove_link(user_info->user_info_entries, last); + } } void * diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/notify.h --- a/libpurple/notify.h Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/notify.h Mon Oct 15 23:46:12 2007 +0000 @@ -539,7 +539,7 @@ void purple_notify_user_info_prepend_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value); /** - * Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object + * Remove a PurpleNotifyUserInfoEntry from a PurpleNotifyUserInfo object without freeing the entry. * * @param user_info The PurpleNotifyUserInfo * @param user_info_entry The PurpleNotifyUserInfoEntry diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/protocols/msn/httpconn.c --- a/libpurple/protocols/msn/httpconn.c Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/protocols/msn/httpconn.c Mon Oct 15 23:46:12 2007 +0000 @@ -687,6 +687,17 @@ g_free(httpconn->host); + while (httpconn->queue != NULL) { + MsnHttpQueueData *queue_data; + + queue_data = (MsnHttpQueueData *) httpconn->queue->data; + + httpconn->queue = g_list_remove_link(httpconn->queue, httpconn->queue); + + g_free(queue_data->body); + g_free(queue_data); + } + purple_circ_buffer_destroy(httpconn->tx_buf); if (httpconn->tx_handler > 0) purple_input_remove(httpconn->tx_handler); diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/protocols/msn/msn.c Mon Oct 15 23:46:12 2007 +0000 @@ -1594,7 +1594,6 @@ gboolean sect_info = FALSE; gboolean has_contact_info = FALSE; char *url_buffer; - GString *s, *s2; int stripped_len; #if PHOTO_SUPPORT char *photo_url_text = NULL; @@ -1679,11 +1678,6 @@ purple_debug_misc("msn", "stripped = %p\n", stripped); purple_debug_misc("msn", "url_buffer = %p\n", url_buffer); - /* Gonna re-use the memory we've already got for url_buffer */ - /* No we're not. */ - s = g_string_sized_new(strlen(url_buffer)); - s2 = g_string_sized_new(strlen(url_buffer)); - /* General section header */ if (has_tooltip_text) purple_notify_user_info_add_section_break(user_info); @@ -2030,7 +2024,7 @@ purple_debug_warning("msn", "invalid connection. ignoring buddy photo info.\n"); g_free(stripped); g_free(url_buffer); - g_free(user_info); + purple_notify_user_info_destroy(user_info); g_free(info_data->name); g_free(info_data); g_free(photo_url_text); diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/protocols/msn/slplink.c --- a/libpurple/protocols/msn/slplink.c Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/protocols/msn/slplink.c Mon Oct 15 23:46:12 2007 +0000 @@ -120,6 +120,8 @@ while (slplink->slp_calls != NULL) msn_slp_call_destroy(slplink->slp_calls->data); + g_queue_free(slplink->slp_msg_queue); + session->slplinks = g_list_remove(session->slplinks, slplink); diff -r 37f3c1023a68 -r 1ec2b67e9bc1 libpurple/protocols/msn/switchboard.c --- a/libpurple/protocols/msn/switchboard.c Mon Oct 15 23:46:02 2007 +0000 +++ b/libpurple/protocols/msn/switchboard.c Mon Oct 15 23:46:12 2007 +0000 @@ -108,8 +108,8 @@ g_free(swboard->auth_key); g_free(swboard->session_id); - for (l = swboard->users; l != NULL; l = l->next) - g_free(l->data); + for (; swboard->users; swboard->users = g_list_remove_link(swboard->users, swboard->users)) + g_free(swboard->users->data); session = swboard->session; session->switches = g_list_remove(session->switches, swboard); diff -r 37f3c1023a68 -r 1ec2b67e9bc1 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Mon Oct 15 23:46:02 2007 +0000 +++ b/pidgin/gtkblist.c Mon Oct 15 23:46:12 2007 +0000 @@ -3907,7 +3907,7 @@ convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, TRUE, 1); if (convs) { - purple_conversation_present((PurpleConversation*)convs->data); + pidgin_conv_present_conversation((PurpleConversation*)convs->data); g_list_free(convs); } break; diff -r 37f3c1023a68 -r 1ec2b67e9bc1 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Mon Oct 15 23:46:02 2007 +0000 +++ b/pidgin/gtkconv.c Mon Oct 15 23:46:12 2007 +0000 @@ -148,6 +148,7 @@ static void add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name); static gboolean tab_complete(PurpleConversation *conv); static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); +static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state); static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); static void update_typing_icon(PidginConversation *gtkconv); static const char *item_factory_translate_func (const char *path, gpointer func_data); @@ -2853,8 +2854,9 @@ if (gtkconv != NULL && gtkconv->active_conv != conv) continue; if (gtkconv == NULL) { - if (!hidden_only || - !purple_conversation_get_data(conv, "unseen-count")) + if (!purple_conversation_get_data(conv, "unseen-count") || + !purple_conversation_get_data(conv, "unseen-state") || + GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))create_conversation = pidgin_conv_new; + } else { + /* TODO: update the unseen_state data on the conv here */ } } else { /* new message for an IM */ @@ -6668,13 +6673,24 @@ static void wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message, - PurpleConversation *conv, PurpleMessageFlags flag, gpointer null) + PurpleConversation *conv, PurpleMessageFlags flags, gpointer null) { if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv)) return; - if (flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) { - purple_conversation_set_data(conv, "unseen-count", - GINT_TO_POINTER(GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")) + 1)); + if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) { + PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; + + if ((flags & PURPLE_MESSAGE_NICK) == PURPLE_MESSAGE_NICK) + unseen = PIDGIN_UNSEEN_NICK; + else if (((flags & PURPLE_MESSAGE_SYSTEM) == PURPLE_MESSAGE_SYSTEM) || + ((flags & PURPLE_MESSAGE_ERROR) == PURPLE_MESSAGE_ERROR)) + unseen = PIDGIN_UNSEEN_EVENT; + else if ((flags & PURPLE_MESSAGE_NO_LOG) == PURPLE_MESSAGE_NO_LOG) + unseen = PIDGIN_UNSEEN_NO_LOG; + else + unseen = PIDGIN_UNSEEN_TEXT; + + conv_set_unseen(conv, unseen); purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); } } @@ -7449,6 +7465,7 @@ return FALSE; purple_conversation_set_data(conv, "unseen-count", NULL); + purple_conversation_set_data(conv, "unseen-state", NULL); purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); private_gtkconv_new(conv, FALSE); gtkconv = PIDGIN_CONVERSATION(conv); @@ -7918,6 +7935,38 @@ } static void +conv_set_unseen(PurpleConversation *conv, PidginUnseenState state) +{ + int unseen_count = 0; + PidginUnseenState unseen_state = PIDGIN_UNSEEN_NONE; + + if(purple_conversation_get_data(conv, "unseen-count")) + unseen_count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")); + + if(purple_conversation_get_data(conv, "unseen-state")) + unseen_state = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state")); + + if (state == PIDGIN_UNSEEN_NONE) + { + unseen_count = 0; + unseen_state = PIDGIN_UNSEEN_NONE; + } + else + { + if (state >= PIDGIN_UNSEEN_TEXT) + unseen_count++; + + if (state > unseen_state) + unseen_state = state; + } + + purple_conversation_set_data(conv, "unseen-count", GINT_TO_POINTER(unseen_count)); + purple_conversation_set_data(conv, "unseen-state", GINT_TO_POINTER(unseen_state)); + + purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); +} + +static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state) { if (state == PIDGIN_UNSEEN_NONE) diff -r 37f3c1023a68 -r 1ec2b67e9bc1 pidgin/gtkdocklet.c --- a/pidgin/gtkdocklet.c Mon Oct 15 23:46:02 2007 +0000 +++ b/pidgin/gtkdocklet.c Mon Oct 15 23:46:12 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" @@ -144,15 +145,22 @@ if (ui_ops->set_tooltip) { GString *tooltip_text = g_string_new(""); for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) { - if (PIDGIN_IS_PIDGIN_CONVERSATION(l->data)) { - PidginConversation *gtkconv = PIDGIN_CONVERSATION((PurpleConversation *)l->data); - if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) - g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); - else - g_string_append_printf(tooltip_text, - ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), - gtkconv->unseen_count, - gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); + PurpleConversation *conv = (PurpleConversation *)l->data; + PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); + + if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) { + g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); + } else if(gtkconv) { + g_string_append_printf(tooltip_text, + ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), + gtkconv->unseen_count, + gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); + } else { + g_string_append_printf(tooltip_text, + ngettext("%d unread message from %s\n", "%d unread messages from %s\n", + GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))), + GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")), + purple_conversation_get_name(conv)); } } @@ -356,6 +364,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 +381,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 +458,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 +501,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) @@ -653,7 +765,7 @@ if (pending) { GList *l = get_pending_list(1); if (l != NULL) { - purple_conversation_present((PurpleConversation *)l->data); + pidgin_conv_present_conversation((PurpleConversation *)l->data); g_list_free(l); } } else {