# HG changeset patch # User William Ehlhardt # Date 1182807520 0 # Node ID 22838745420afc587a5a947ae44cc8667d38947f # Parent 3c6bf77bf7c4ca7c3911578609ecebf114bff826# Parent 51ebbe199514fd71fd066fa2ab9c345c336a38d6 propagate from branch 'im.pidgin.pidgin' (head 704b8c18f7c29f1fc8bfcf640275d2a9928ed03c) to branch 'im.pidgin.soc.2007.certmgr' (head 66c83d19227970a035a46be54fb419e0d9102d44) diff -r 3c6bf77bf7c4 -r 22838745420a COPYRIGHT --- a/COPYRIGHT Sat Jun 23 20:34:07 2007 +0000 +++ b/COPYRIGHT Mon Jun 25 21:38:40 2007 +0000 @@ -276,6 +276,7 @@ Julien Pivotto Ari Pollak Robey Pointer +Eric Polino Stephen Pope Nathan Poznick Jory A. Pratt @@ -355,6 +356,7 @@ Cestonaro Thilo Will Thompson Douglas Thrift (douglaswth) +Mark Tiefenbruck Andrew Tinney Jeffery To Warren Togami diff -r 3c6bf77bf7c4 -r 22838745420a finch/gntconv.c --- a/finch/gntconv.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/gntconv.c Mon Jun 25 21:38:40 2007 +0000 @@ -485,7 +485,24 @@ gnt_box_set_title(GNT_BOX(ggc->window), title); gnt_box_set_toplevel(GNT_BOX(ggc->window), TRUE); gnt_box_set_pad(GNT_BOX(ggc->window), 0); - gnt_widget_set_name(ggc->window, "conversation-window"); + + switch(conv->type){ + case PURPLE_CONV_TYPE_UNKNOWN: + gnt_widget_set_name(ggc->window, "conversation-window-unknown" ); + break; + case PURPLE_CONV_TYPE_IM: + gnt_widget_set_name(ggc->window, "conversation-window-im" ); + break; + case PURPLE_CONV_TYPE_CHAT: + gnt_widget_set_name(ggc->window, "conversation-window-chat" ); + break; + case PURPLE_CONV_TYPE_MISC: + gnt_widget_set_name(ggc->window, "conversation-window-misc" ); + break; + case PURPLE_CONV_TYPE_ANY: + gnt_widget_set_name(ggc->window, "conversation-window-any" ); + break; + } gg_create_menu(ggc); @@ -554,7 +571,8 @@ if (ggc->list == NULL) { g_free(ggc->u.chat); - gnt_widget_destroy(ggc->window); + if (ggc->window) + gnt_widget_destroy(ggc->window); g_free(ggc); } } diff -r 3c6bf77bf7c4 -r 22838745420a finch/gntplugin.c --- a/finch/gntplugin.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/gntplugin.c Mon Jun 25 21:38:40 2007 +0000 @@ -47,7 +47,7 @@ static GHashTable *confwins; -static void process_pref_frame(PurplePluginPrefFrame *frame); +static GntWidget *process_pref_frame(PurplePluginPrefFrame *frame); static void decide_conf_button(PurplePlugin *plugin) @@ -84,7 +84,7 @@ gnt_tree_set_choice(GNT_TREE(tree), plugin, TRUE); } - if ((win = g_hash_table_lookup(confwins, plugin)) != NULL) + if (confwins && (win = g_hash_table_lookup(confwins, plugin)) != NULL) { gnt_widget_destroy(win); } @@ -221,7 +221,11 @@ else if (plugin->info->prefs_info && plugin->info->prefs_info->get_plugin_pref_frame) { - process_pref_frame(plugin->info->prefs_info->get_plugin_pref_frame(plugin)); + GntWidget *win = process_pref_frame(plugin->info->prefs_info->get_plugin_pref_frame(plugin)); + if (confwins == NULL) + confwin_init(); + g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(remove_confwin), plugin); + g_hash_table_insert(confwins, plugin, win); return; } else @@ -273,6 +277,14 @@ { PurplePlugin *plug = iter->data; + if (plug->info->type == PURPLE_PLUGIN_LOADER) { + GList *cur; + for (cur = PURPLE_PLUGIN_LOADER_INFO(plug)->exts; cur != NULL; + cur = cur->next) + purple_plugins_probe(cur->data); + continue; + } + if (plug->info->type != PURPLE_PLUGIN_STANDARD || (plug->info->flags & PURPLE_PLUGIN_FLAG_INVISIBLE) || plug->error) @@ -308,7 +320,7 @@ decide_conf_button(gnt_tree_get_selection_data(GNT_TREE(tree))); } -static void +static GntWidget* process_pref_frame(PurplePluginPrefFrame *frame) { PurpleRequestField *field; @@ -360,7 +372,7 @@ } } - purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields, + return purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields, _("Save"), G_CALLBACK(finch_request_save_in_prefs), _("Cancel"), NULL, NULL, NULL, NULL, NULL); diff -r 3c6bf77bf7c4 -r 22838745420a finch/gntrequest.c --- a/finch/gntrequest.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/gntrequest.c Mon Jun 25 21:38:40 2007 +0000 @@ -399,7 +399,7 @@ purple_request_field_string_get_default_value(field)); gnt_entry_set_masked(GNT_ENTRY(entry), purple_request_field_string_is_masked(field)); - if (purple_str_has_prefix(hint, "screenname")) { + if (hint && purple_str_has_prefix(hint, "screenname")) { PurpleBlistNode *node = purple_blist_get_root(); gboolean offline = purple_str_has_suffix(hint, "all"); for (; node; node = purple_blist_node_next(node, offline)) { @@ -673,7 +673,7 @@ switch (pt) { case PURPLE_PREF_INT: { - long int tmp; + long int tmp = GPOINTER_TO_INT(val); if (type == PURPLE_REQUEST_FIELD_LIST) /* Lists always return string */ sscanf(val, "%ld", &tmp); purple_prefs_set_int(id, (gint)tmp); diff -r 3c6bf77bf7c4 -r 22838745420a finch/libgnt/gntwidget.c --- a/finch/libgnt/gntwidget.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/libgnt/gntwidget.c Mon Jun 25 21:38:40 2007 +0000 @@ -576,7 +576,7 @@ GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0); } - else if (!set) + else if (!set && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) { GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0); diff -r 3c6bf77bf7c4 -r 22838745420a finch/libgnt/gntwm.c --- a/finch/libgnt/gntwm.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/libgnt/gntwm.c Mon Jun 25 21:38:40 2007 +0000 @@ -1458,50 +1458,50 @@ static gboolean match_title(gpointer title, gpointer n, gpointer wid_title) { - /* maybe check for regex.h? */ + /* XXX: do any regex magic here. */ if (g_strrstr((gchar *)wid_title, (gchar *)title)) return TRUE; return FALSE; } #if !GLIB_CHECK_VERSION(2,4,0) -typedef struct +struct { - GntWM *wm; - GntWS *ret; - gchar *title; -} title_search; + gpointer data; + gpointer value; +} table_find_data; -static void match_title_search(gpointer key, gpointer value, gpointer search) +static void +table_find_helper(gpointer key, gpointer value, gpointer data) { - title_search *s = search; - if (s->ret) - return; - if (match_title(key, NULL, s->title)) - s->ret = g_hash_table_lookup(s->wm->title_places, key); + GHRFunc func = data; + if (func(key, value, table_find_data.data)) + table_find_data.value = value; +} + +static gpointer +g_hash_table_find(GHashTable * table, GHRFunc func, gpointer data) +{ + table_find_data.data = data; + table_find_data.value = NULL; + g_hash_table_foreach(table, table_find_helper, func); + return table_find_data.value; } #endif static GntWS * -new_widget_find_workspace(GntWM *wm, GntWidget *widget, gchar *wid_title) +new_widget_find_workspace(GntWM *wm, GntWidget *widget) { - GntWS *ret; - const gchar *name; -#if GLIB_CHECK_VERSION(2,4,0) - ret = g_hash_table_find(wm->title_places, match_title, wid_title); -#else - title_search *s = NULL; - s = g_new0(title_search, 1); - s->wm = wm; - s->title = wid_title; - g_hash_table_foreach(wm->title_places, match_title_search, s); - ret = s->ret; -#endif + GntWS *ret = NULL; + const gchar *name, *title; + title = GNT_BOX(widget)->title; + if (title) + ret = g_hash_table_find(wm->title_places, match_title, (gpointer)title); if (ret) return ret; name = gnt_widget_get_name(widget); if (name) - ret = g_hash_table_lookup(wm->name_places, name); + ret = g_hash_table_find(wm->name_places, match_title, (gpointer)name); return ret ? ret : wm->cws; } @@ -1564,8 +1564,7 @@ GntWidget *w = NULL; if (GNT_IS_BOX(widget)) { - char *title = GNT_BOX(widget)->title; - ws = new_widget_find_workspace(wm, widget, title); + ws = new_widget_find_workspace(wm, widget); } if (ws->ordered) diff -r 3c6bf77bf7c4 -r 22838745420a finch/libgnt/gntws.c --- a/finch/libgnt/gntws.c Sat Jun 23 20:34:07 2007 +0000 +++ b/finch/libgnt/gntws.c Mon Jun 25 21:38:40 2007 +0000 @@ -87,8 +87,12 @@ void gnt_ws_add_widget(GntWS *ws, GntWidget* wid) { + GntWidget *oldfocus; + oldfocus = ws->ordered ? ws->ordered->data : NULL; ws->list = g_list_append(ws->list, wid); ws->ordered = g_list_prepend(ws->ordered, wid); + if (oldfocus) + gnt_widget_set_focus(oldfocus, FALSE); } void gnt_ws_remove_widget(GntWS *ws, GntWidget* wid) diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/core.c --- a/libpurple/core.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/core.c Mon Jun 25 21:38:40 2007 +0000 @@ -222,11 +222,10 @@ purple_sound_uninit(); purple_plugins_uninit(); - purple_signals_uninit(); - #ifdef HAVE_DBUS purple_dbus_uninit(); #endif + purple_signals_uninit(); g_free(core->ui); g_free(core); diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/plugins/perl/scripts/signals-test.pl --- a/libpurple/plugins/perl/scripts/signals-test.pl Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/plugins/perl/scripts/signals-test.pl Mon Jun 25 21:38:40 2007 +0000 @@ -7,7 +7,7 @@ name => "Perl: $MODULE_NAME", version => "0.1", summary => "Signals Test plugin for the Perl interpreter.", - description => "Demonstrate the user of purple signals from " . + description => "Demonstrate the use of purple signals from " . "a perl plugin.", author => "Sadrul Habib Chowdhury ", url => "http://developer.pidgin.im/wiki/sadrul/", diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/bonjour/buddy.c --- a/libpurple/protocols/bonjour/buddy.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/bonjour/buddy.c Mon Jun 25 21:38:40 2007 +0000 @@ -17,6 +17,7 @@ #include #include +#include "internal.h" #include "buddy.h" #include "account.h" #include "blist.h" diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/bonjour/jabber.c --- a/libpurple/protocols/bonjour/jabber.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/bonjour/jabber.c Mon Jun 25 21:38:40 2007 +0000 @@ -31,6 +31,7 @@ #include #include +#include "internal.h" #include "network.h" #include "eventloop.h" #include "connection.h" diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/bonjour/mdns_common.c --- a/libpurple/protocols/bonjour/mdns_common.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_common.c Mon Jun 25 21:38:40 2007 +0000 @@ -16,6 +16,7 @@ #include +#include "internal.h" #include "config.h" #include "mdns_common.h" #include "bonjour.h" diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/bonjour/mdns_win32.c --- a/libpurple/protocols/bonjour/mdns_win32.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/bonjour/mdns_win32.c Mon Jun 25 21:38:40 2007 +0000 @@ -14,6 +14,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "internal.h" #include "mdns_win32.h" #include "debug.h" diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/.todo --- a/libpurple/protocols/jabber/.todo Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/.todo Mon Jun 25 21:38:40 2007 +0000 @@ -1,13 +1,4 @@ - - *sigh* file transfer (do we really need/want this?) - - faceprint did this - - - - problem seeing buddies with long blist? - Browsing @@ -17,12 +8,6 @@ Add option for user info to be published or not in JUD. - - Show self on buddylist - - is this done? - - Delete server account. @@ -37,9 +22,6 @@ formatted. enhancement-request so that the birthday field in the setinfo form would split up into relevant fields allowing for a strict syntax (like year--month--day or so, perhaps even dropdown menus) - - have set info pre-fill values from the server when no local vcard exists. this will help people migrating to libpurple-based clients - Jabber Transports (having them show up on the buddy list should be fairly easy; having an appropriate right-click menu for them should also be somewhat easy. Providing a UI for adding transports should be rather difficult.) diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/buddy.c Mon Jun 25 21:38:40 2007 +0000 @@ -419,6 +419,10 @@ avatar_data = purple_imgstore_get_data(img); avatar_len = purple_imgstore_get_size(img); + /* have to get rid of the old PHOTO if it exists */ + if((photo = xmlnode_get_child(vc_node, "PHOTO"))) { + xmlnode_free(photo); + } photo = xmlnode_new_child(vc_node, "PHOTO"); binval = xmlnode_new_child(photo, "BINVAL"); enc = purple_base64_encode(avatar_data, avatar_len); diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/disco.c --- a/libpurple/protocols/jabber/disco.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/disco.c Mon Jun 25 21:38:40 2007 +0000 @@ -83,6 +83,7 @@ SUPPORT_FEATURE("jabber:iq:last") SUPPORT_FEATURE("jabber:iq:oob") SUPPORT_FEATURE("jabber:iq:time") + SUPPORT_FEATURE("xmpp:urn:time") SUPPORT_FEATURE("jabber:iq:version") SUPPORT_FEATURE("jabber:x:conference") SUPPORT_FEATURE("http://jabber.org/protocol/bytestreams") diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/iq.c --- a/libpurple/protocols/jabber/iq.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/iq.c Mon Jun 25 21:38:40 2007 +0000 @@ -169,7 +169,7 @@ static void jabber_iq_time_parse(JabberStream *js, xmlnode *packet) { - const char *type, *from, *id; + const char *type, *from, *id, *xmlns; JabberIq *iq; xmlnode *query; time_t now_t; @@ -182,27 +182,40 @@ from = xmlnode_get_attrib(packet, "from"); id = xmlnode_get_attrib(packet, "id"); + /* we're gonna throw this away in a moment, but we need it + * to get the xmlns, so we can figure out if this is + * jabber:iq:time or urn:xmpp:time */ + query = xmlnode_get_child(packet, "query"); + xmlns = xmlnode_get_namespace(query); + if(type && !strcmp(type, "get")) { + xmlnode *utc; const char *date; - iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time"); + iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, xmlns); jabber_iq_set_id(iq, id); xmlnode_set_attrib(iq->node, "to", from); query = xmlnode_get_child(iq->node, "query"); date = purple_utf8_strftime("%Y%m%dT%T", now); - xmlnode_insert_data(xmlnode_new_child(query, "utc"), date, -1); + utc = xmlnode_new_child(query, "utc"); + xmlnode_insert_data(utc, date, -1); + + if(!strcmp("urn:xmpp:time", xmlns)) { + xmlnode_insert_data(utc, "Z", 1); /* of COURSE the thing that is the same is different */ - date = purple_utf8_strftime("%Z", now); - xmlnode_insert_data(xmlnode_new_child(query, "tz"), date, -1); + date = purple_get_tzoff_str(now, TRUE); + xmlnode_insert_data(xmlnode_new_child(query, "tzo"), date, -1); + } else { /* jabber:iq:time */ + date = purple_utf8_strftime("%Z", now); + xmlnode_insert_data(xmlnode_new_child(query, "tz"), date, -1); - date = purple_utf8_strftime("%d %b %Y %T", now); - xmlnode_insert_data(xmlnode_new_child(query, "display"), date, -1); + date = purple_utf8_strftime("%d %b %Y %T", now); + xmlnode_insert_data(xmlnode_new_child(query, "display"), date, -1); + } jabber_iq_send(iq); - } else { - /* XXX: error */ } } @@ -347,6 +360,7 @@ jabber_iq_register_handler("http://jabber.org/protocol/bytestreams", jabber_bytestreams_parse); jabber_iq_register_handler("jabber:iq:last", jabber_iq_last_parse); jabber_iq_register_handler("jabber:iq:time", jabber_iq_time_parse); + jabber_iq_register_handler("urn:xmpp:time", jabber_iq_time_parse); jabber_iq_register_handler("jabber:iq:version", jabber_iq_version_parse); jabber_iq_register_handler("http://jabber.org/protocol/disco#info", jabber_disco_info_parse); jabber_iq_register_handler("http://jabber.org/protocol/disco#items", jabber_disco_items_parse); diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/jabber.c Mon Jun 25 21:38:40 2007 +0000 @@ -1114,9 +1114,11 @@ char *jabber_status_text(PurpleBuddy *b) { - JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name, - FALSE); char *ret = NULL; + JabberBuddy *jb = NULL; + + if (b->account->gc && b->account->gc->proto_data) + jb = jabber_buddy_find(b->account->gc->proto_data, b->name, FALSE); if(jb && !PURPLE_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) { ret = g_strdup(_("Not Authorized")); diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/jabber/presence.c --- a/libpurple/protocols/jabber/presence.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/jabber/presence.c Mon Jun 25 21:38:40 2007 +0000 @@ -515,7 +515,7 @@ buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", jid->node ? "@" : "", jid->domain); if((b = purple_find_buddy(js->gc->account, buddy_name)) == NULL) { - purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)", + purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%x)\n", buddy_name, purple_account_get_username(js->gc->account), js->gc->account); jabber_id_free(jid); g_free(avatar_hash); @@ -565,9 +565,7 @@ } if((found_jbr = jabber_buddy_find_resource(jb, NULL))) { - if(!jbr || jbr == found_jbr) { - purple_prpl_got_user_status(js->gc->account, buddy_name, jabber_buddy_state_get_status_id(state), "priority", found_jbr->priority, found_jbr->status ? "message" : NULL, found_jbr->status, NULL); - } + purple_prpl_got_user_status(js->gc->account, buddy_name, jabber_buddy_state_get_status_id(state), "priority", found_jbr->priority, found_jbr->status ? "message" : NULL, found_jbr->status, NULL); } else { purple_prpl_got_user_status(js->gc->account, buddy_name, "offline", status ? "message" : NULL, status, NULL); } diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/oscar/family_auth.c --- a/libpurple/protocols/oscar/family_auth.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/oscar/family_auth.c Mon Jun 25 21:38:40 2007 +0000 @@ -211,7 +211,7 @@ #ifdef USE_XOR_FOR_ICQ /* If we're signing on an ICQ account then use the older, XOR login method */ - if (isdigit(sn[0])) + if (aim_sn_is_icq(sn)) return goddamnicq2(od, conn, sn, password, ci); #endif @@ -224,7 +224,7 @@ /* Truncate ICQ and AOL passwords, if necessary */ password_len = strlen(password); - if (isdigit(sn[0]) && (password_len > MAXICQPASSLEN)) + if (aim_sn_is_icq(sn) && (password_len > MAXICQPASSLEN)) password_len = MAXICQPASSLEN; else if (truncate_pass && password_len > 8) password_len = 8; @@ -477,7 +477,7 @@ return -EINVAL; #ifdef USE_XOR_FOR_ICQ - if (isdigit(sn[0])) + if (aim_sn_is_icq(sn)) return goddamnicq(od, conn, sn); #endif diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/oscar/oscar.c --- a/libpurple/protocols/oscar/oscar.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/oscar/oscar.c Mon Jun 25 21:38:40 2007 +0000 @@ -425,7 +425,7 @@ charsetstr1 = "UCS-2BE"; charsetstr2 = "UTF-8"; } else if (charset == AIM_CHARSET_CUSTOM) { - if ((sourcesn != NULL) && isdigit(sourcesn[0])) + if ((sourcesn != NULL) && aim_sn_is_icq(sourcesn)) charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); else charsetstr1 = "ISO-8859-1"; @@ -1258,7 +1258,7 @@ if (!aim_snvalid(purple_account_get_username(account))) { gchar *buf; - buf = g_strdup_printf(_("Unable to login: Could not sign on as %s because the screen name is invalid. Screen names must either start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account)); + buf = g_strdup_printf(_("Unable to login: Could not sign on as %s because the screen name is invalid. Screen names must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), purple_account_get_username(account)); gc->wants_to_die = TRUE; purple_connection_error(gc, buf); g_free(buf); @@ -4623,7 +4623,7 @@ if (!aim_snvalid(buddy->name)) { gchar *buf; - buf = g_strdup_printf(_("Could not add the buddy %s because the screen name is invalid. Screen names must either start with a letter and contain only letters, numbers and spaces, or contain only numbers."), buddy->name); + buf = g_strdup_printf(_("Could not add the buddy %s because the screen name is invalid. Screen names must be a valid email address, or start with a letter and contain only letters, numbers and spaces, or contain only numbers."), buddy->name); if (!purple_conv_present_error(buddy->name, purple_connection_get_account(gc), buf)) purple_notify_error(gc, NULL, _("Unable To Add"), buf); g_free(buf); @@ -5060,7 +5060,8 @@ default: { /* La la la */ gchar *buf; purple_debug_error("oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack); - buf = g_strdup_printf(_("Could not add the buddy %s for an unknown reason. The most common reason for this is that you have the maximum number of allowed buddies in your buddy list."), (retval->name ? retval->name : _("(no name)"))); + buf = g_strdup_printf(_("Could not add the buddy %s for an unknown reason."), + (retval->name ? retval->name : _("(no name)"))); if ((retval->name != NULL) && !purple_conv_present_error(retval->name, purple_connection_get_account(gc), buf)) purple_notify_error(gc, NULL, _("Unable To Add"), buf); g_free(buf); diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/oscar/peer.c --- a/libpurple/protocols/oscar/peer.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/oscar/peer.c Mon Jun 25 21:38:40 2007 +0000 @@ -1019,7 +1019,7 @@ PURPLE_DEFAULT_ACTION_NONE, account, sn, NULL, conn, 2, - _("_Connect"), G_CALLBACK(peer_connection_got_proposition_yes_cb), + _("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb), _("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb)); } else if (args->type == OSCAR_CAPABILITY_SENDFILE) diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/oscar/util.c --- a/libpurple/protocols/oscar/util.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/oscar/util.c Mon Jun 25 21:38:40 2007 +0000 @@ -37,6 +37,7 @@ * -- DMP. * */ +/* TODO: Get rid of this and use glib functions */ int aimutil_tokslen(char *toSearch, int theindex, char dl) { @@ -138,6 +139,7 @@ * Check if the given screen name is a valid AIM screen name. * Example: BobDole * Example: Henry_Ford@mac.com + * Example: 1KrazyKat@example.com * * @return TRUE if the screen name is valid, FALSE if not. */ @@ -146,9 +148,16 @@ { int i; + if (purple_email_is_valid(sn)) + return TRUE; + + /* Normal AIM screen names can't start with a number */ + if (isdigit(sn[0])) + return FALSE; + for (i = 0; sn[i] != '\0'; i++) { if (!isalnum(sn[i]) && (sn[i] != ' ') && - (sn[i] != '@') && (sn[i] != '.') && + (sn[i] != '.') && (sn[i] != '_') && (sn[i] != '-')) return FALSE; } @@ -169,10 +178,10 @@ for (i = 0; sn[i] != '\0'; i++) { if (!isdigit(sn[i])) - return 0; + return FALSE; } - return 1; + return TRUE; } /** @@ -187,14 +196,14 @@ int i; if (sn[0] != '+') - return 0; + return FALSE; for (i = 1; sn[i] != '\0'; i++) { if (!isdigit(sn[i])) - return 0; + return FALSE; } - return 1; + return TRUE; } /** @@ -206,70 +215,37 @@ aim_snvalid(const char *sn) { if ((sn == NULL) || (*sn == '\0')) - return 0; + return FALSE; - if (isalpha(sn[0])) - return aim_snvalid_aim(sn); - else if (isdigit(sn[0])) - return aim_snvalid_icq(sn); - else if (sn[0] == '+') - return aim_snvalid_sms(sn); - - return 0; + return aim_snvalid_icq(sn) || aim_snvalid_sms(sn) || aim_snvalid_aim(sn); } /** * Determine if a given screen name is an ICQ screen name - * (i.e. it begins with a number). + * (i.e. it is composed of only numbers). * - * @sn A valid AIM or ICQ screen name. + * @param sn A valid AIM or ICQ screen name. * @return TRUE if the screen name is an ICQ screen name. Otherwise * FALSE is returned. */ gboolean aim_sn_is_icq(const char *sn) { - if (isalpha(sn[0])) - return FALSE; - return TRUE; + return aim_snvalid_icq(sn); } /** * Determine if a given screen name is an SMS number * (i.e. it begins with a +). * - * @sn A valid AIM or ICQ screen name. + * @param sn A valid AIM or ICQ screen name. * @return TRUE if the screen name is an SMS number. Otherwise * FALSE is returned. */ gboolean aim_sn_is_sms(const char *sn) { - if (sn[0] != '+') - return FALSE; - return TRUE; -} - -/** - * This takes a screen name and returns its length without - * spaces. If there are no spaces in the SN, then the - * return is equal to that of strlen(). - */ -int -aim_snlen(const char *sn) -{ - int i = 0; - - if (!sn) - return 0; - - while (*sn != '\0') { - if (*sn != ' ') - i++; - sn++; - } - - return i; + return (sn[0] == '+'); } /** @@ -279,9 +255,9 @@ * ignored, with the exception that screen names can not start with * a space). * - * Return: 0 if equal - * non-0 if different + * @return 0 if equal, non-0 if different */ +/* TODO: Do something different for email addresses. */ int aim_sncmp(const char *sn1, const char *sn2) { diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/protocols/qq/Makefile.mingw --- a/libpurple/protocols/qq/Makefile.mingw Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/protocols/qq/Makefile.mingw Mon Jun 25 21:38:40 2007 +0000 @@ -54,7 +54,6 @@ group_im.c \ group_info.c \ group_join.c \ - group_misc.c \ group_network.c \ group_opt.c \ group_search.c \ diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/server.c --- a/libpurple/server.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/server.c Mon Jun 25 21:38:40 2007 +0000 @@ -198,7 +198,7 @@ { PurplePluginProtocolInfo *prpl_info = NULL; - if (b != NULL && b->account->gc->prpl != NULL) + if (b != NULL && b->account->gc && b->account->gc->prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(b->account->gc->prpl); if (b && prpl_info && prpl_info->alias_buddy) { diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/status.c --- a/libpurple/status.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/status.c Mon Jun 25 21:38:40 2007 +0000 @@ -152,10 +152,10 @@ { PURPLE_STATUS_UNSET, "unset", N_("Unset") }, { PURPLE_STATUS_OFFLINE, "offline", N_("Offline") }, { PURPLE_STATUS_AVAILABLE, "available", N_("Available") }, - { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Unavailable") }, + { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Do not disturb") }, { PURPLE_STATUS_INVISIBLE, "invisible", N_("Invisible") }, { PURPLE_STATUS_AWAY, "away", N_("Away") }, - { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended Away") }, + { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended away") }, { PURPLE_STATUS_MOBILE, "mobile", N_("Mobile") } }; diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/util.c --- a/libpurple/util.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/util.c Mon Jun 25 21:38:40 2007 +0000 @@ -531,10 +531,9 @@ } #endif -#ifndef HAVE_STRFTIME_Z_FORMAT -static const char *get_tmoff(const struct tm *tm) +const char *purple_get_tzoff_str(const struct tm *tm, gboolean iso) { - static char buf[6]; + static char buf[7]; long off; gint8 min; gint8 hrs; @@ -554,7 +553,7 @@ # else # ifdef HAVE_TIMEZONE tzset(); - off = -timezone; + off = -1 * timezone; # endif /* HAVE_TIMEZONE */ # endif /* !HAVE_TM_GMTOFF */ #endif /* _WIN32 */ @@ -562,12 +561,22 @@ min = (off / 60) % 60; hrs = ((off / 60) - min) / 60; - if (g_snprintf(buf, sizeof(buf), "%+03d%02d", hrs, ABS(min)) > 5) - g_return_val_if_reached(""); + if(iso) { + if (0 == off) { + strcpy(buf, "Z"); + } else { + /* please leave the colons...they're optional for iso, but jabber + * wants them */ + if(g_snprintf(buf, sizeof(buf), "%+03d:%02d", hrs, ABS(min)) > 6) + g_return_val_if_reached(""); + } + } else { + if (g_snprintf(buf, sizeof(buf), "%+03d%02d", hrs, ABS(min)) > 5) + g_return_val_if_reached(""); + } return buf; } -#endif /* Windows doesn't HAVE_STRFTIME_Z_FORMAT, but this seems clearer. -- rlaager */ #if !defined(HAVE_STRFTIME_Z_FORMAT) || defined(_WIN32) @@ -600,7 +609,7 @@ fmt ? fmt : "", c - start - 1, start, - get_tmoff(tm)); + purple_get_tzoff_str(tm, FALSE)); g_free(fmt); fmt = tmp; start = c + 1; diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/util.h --- a/libpurple/util.h Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/util.h Mon Jun 25 21:38:40 2007 +0000 @@ -257,6 +257,16 @@ const char *purple_utf8_strftime(const char *format, const struct tm *tm); /** + * Gets a string representation of the local timezone offset + * + * @param tm The time to get the timezone for + * @param iso TRUE to format the offset according to ISO-8601, FALSE to + * not substitute 'Z' for 0 offset, and to not separate + * hours and minutes with a colon. + */ +const char *purple_get_tzoff_str(const struct tm *tm, gboolean iso); + +/** * Formats a time into the user's preferred short date format. * * The returned string is stored in a static buffer, so the result diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/win32/win32dep.c --- a/libpurple/win32/win32dep.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/win32/win32dep.c Mon Jun 25 21:38:40 2007 +0000 @@ -32,6 +32,7 @@ #include #include +#include "internal.h" #include "debug.h" #include "notify.h" diff -r 3c6bf77bf7c4 -r 22838745420a libpurple/xmlnode.c --- a/libpurple/xmlnode.c Sat Jun 23 20:34:07 2007 +0000 +++ b/libpurple/xmlnode.c Mon Jun 25 21:38:40 2007 +0000 @@ -268,6 +268,22 @@ g_return_if_fail(node != NULL); + /* if we're part of a tree, remove ourselves from the tree first */ + if(NULL != node->parent) { + if(node->parent->child == node) { + node->parent->child = node->next; + } else { + xmlnode *prev = node->parent->child; + while(prev && prev->next != node) { + prev = prev->next; + } + if(prev) { + prev->next = node->next; + } + } + } + + /* now free our children */ x = node->child; while(x) { y = x->next; @@ -275,6 +291,7 @@ x = y; } + /* now dispose of ourselves */ g_free(node->name); g_free(node->data); g_free(node->xmlns); diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/eggtrayicon.c --- a/pidgin/eggtrayicon.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/eggtrayicon.c Mon Jun 25 21:38:40 2007 +0000 @@ -152,6 +152,26 @@ } } +static Display * +egg_tray_icon_get_x_display(EggTrayIcon *icon) +{ + Display *xdisplay = NULL; + +#if GTK_CHECK_VERSION(2,1,0) + { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon)); + if (!GDK_IS_DISPLAY (display)) + display = gdk_display_get_default (); + + xdisplay = GDK_DISPLAY_XDISPLAY (display); + } +#else + xdisplay = gdk_display; +#endif + + return xdisplay; +} + static void egg_tray_icon_get_orientation_property (EggTrayIcon *icon) { @@ -168,11 +188,10 @@ g_return_if_fail(icon->manager_window != None); -#if GTK_CHECK_VERSION(2,1,0) - xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); -#else - xdisplay = gdk_display; -#endif + xdisplay = egg_tray_icon_get_x_display(icon); + + if (xdisplay == NULL) + return; gdk_error_trap_push (); type = None; @@ -321,11 +340,10 @@ if (icon->manager_window != None) return; -#if GTK_CHECK_VERSION(2,1,0) - xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); -#else - xdisplay = gdk_display; -#endif + xdisplay = egg_tray_icon_get_x_display(icon); + + if (xdisplay == NULL) + return; XGrabServer (xdisplay); @@ -424,12 +442,15 @@ make_transparent (widget, NULL); + xdisplay = egg_tray_icon_get_x_display(icon); + + if (xdisplay == NULL) + return; + #if GTK_CHECK_VERSION(2,1,0) screen = gdk_screen_get_number (gtk_widget_get_screen (widget)); - xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)); #else screen = XScreenNumberOfScreen (DefaultScreenOfDisplay (gdk_display)); - xdisplay = gdk_display; #endif /* Now see if there's a manager window around */ @@ -519,11 +540,10 @@ XClientMessageEvent ev; Display *xdisplay; -#if GTK_CHECK_VERSION(2,1,0) - xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon))); -#else - xdisplay = gdk_display; -#endif + xdisplay = egg_tray_icon_get_x_display(icon); + + if (xdisplay == NULL) + return; ev.type = ClientMessage; ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon)); diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/gtkblist.c Mon Jun 25 21:38:40 2007 +0000 @@ -174,6 +174,7 @@ static gboolean gtk_blist_window_state_cb(GtkWidget *w, GdkEventWindowState *event, gpointer data) { +#if GTK_CHECK_VERSION(2,2,0) if(event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) { if(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE); @@ -195,6 +196,28 @@ if (!(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) pidgin_blist_refresh_timer(purple_get_blist()); } +#else + /* At least gtk+ 2.0.6 does not properly set the change_mask when unsetting a + * GdkWindowState flag. To work around, the window state will be explicitly + * queried on these older versions of gtk+. See pidgin ticket #739. + */ + GdkWindowState new_window_state = gdk_window_get_state(G_OBJECT(gtkblist->window->window)); + + if(new_window_state & GDK_WINDOW_STATE_WITHDRAWN) { + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", FALSE); + } else { + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_visible", TRUE); + pidgin_blist_refresh_timer(purple_get_blist()); + } + + if(new_window_state & GDK_WINDOW_STATE_MAXIMIZED) + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", TRUE); + else + purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/blist/list_maximized", FALSE); + + if (!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) + pidgin_blist_refresh_timer(purple_get_blist()); +#endif return FALSE; } @@ -2976,10 +2999,11 @@ signon = purple_presence_get_login_time(presence); if (full && PURPLE_BUDDY_IS_ONLINE(b) && signon > 0) { - if (time(NULL) - signon > 63072000 /* 2 years */) { + if (signon > time(NULL)) { /* - * Our local clock must be wrong, show the actual - * date instead of "4 days", etc. + * They signed on in the future?! Our local clock + * must be wrong, show the actual date instead of + * "4 days", etc. */ tmp = g_strdup(purple_date_format_long(localtime(&signon))); } else diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/gtkconv.c Mon Jun 25 21:38:40 2007 +0000 @@ -184,6 +184,8 @@ static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); +static gboolean infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); +static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { static GdkColor col; @@ -4377,7 +4379,7 @@ static GtkWidget * setup_common_pane(PidginConversation *gtkconv) { - GtkWidget *paned, *vbox, *frame, *imhtml_sw; + GtkWidget *paned, *vbox, *frame, *imhtml_sw, *event_box; GtkCellRenderer *rend; GtkTreePath *path; PurpleConversation *conv = gtkconv->active_conv; @@ -4393,9 +4395,19 @@ gtk_widget_show(vbox); /* Setup the info pane */ + event_box = gtk_event_box_new(); + gtk_widget_show(event_box); gtkconv->infopane_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), gtkconv->infopane_hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), event_box, FALSE, FALSE, 0); + gtk_container_add(GTK_CONTAINER(event_box), gtkconv->infopane_hbox); gtk_widget_show(gtkconv->infopane_hbox); + gtk_widget_add_events(event_box, + GDK_BUTTON1_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); + g_signal_connect(G_OBJECT(event_box), "button_press_event", + G_CALLBACK(infopane_press_cb), gtkconv); + g_signal_connect(G_OBJECT(event_box), "button_release_event", + G_CALLBACK(infopane_release_cb), gtkconv); + gtkconv->infopane = gtk_cell_view_new(); gtkconv->infopane_model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING); @@ -7594,6 +7606,45 @@ /* * THANK YOU GALEON! */ + +static gboolean +infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) +{ + int nb_x, nb_y; + + if (e->button != 1 || e->type != GDK_BUTTON_PRESS) + return FALSE; + + if (gtkconv->win->in_drag) { + purple_debug(PURPLE_DEBUG_WARNING, "gtkconv", + "Already in the middle of a window drag at tab_press_cb\n"); + return TRUE; + } + + gtkconv->win->in_predrag = TRUE; + gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); + + gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); + + gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; + gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; + gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; + gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; + + + /* Connect the new motion signals. */ + gtkconv->win->drag_motion_signal = + g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", + G_CALLBACK(notebook_motion_cb), gtkconv->win); + + gtkconv->win->drag_leave_signal = + g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", + G_CALLBACK(notebook_leave_cb), gtkconv->win); + + return FALSE; + +} + static gboolean notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win) { @@ -7683,6 +7734,12 @@ } static gboolean +infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) +{ + return FALSE; +} + +static gboolean notebook_release_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win) { PidginWindow *dest_win; @@ -8013,6 +8070,11 @@ return FALSE; } + if (!purple_account_is_connected(gtkconv->active_conv->account)) { + /* Do not allow aliasing someone on a disconnected account. */ + return FALSE; + } + /* alias label */ entry = gtk_entry_new(); gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); @@ -8374,8 +8436,7 @@ /* Er, bug in notebooks? Switch to the page manually. */ gtk_notebook_set_current_page(GTK_NOTEBOOK(win->notebook), 0); - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), - purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs")); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); } else gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), TRUE); @@ -8491,14 +8552,16 @@ gtk_notebook_remove_page(GTK_NOTEBOOK(win->notebook), index); - /* go back to tabless if need be */ + /* go back to tabless */ if (pidgin_conv_window_get_gtkconv_count(win) <= 2) { - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), - purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs")); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); } win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); + if (!win->gtkconvs || !win->gtkconvs->next) + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); + if (!win->gtkconvs && win != hidden_convwin) pidgin_conv_window_destroy(win); } diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/gtkprivacy.c --- a/pidgin/gtkprivacy.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/gtkprivacy.c Mon Jun 25 21:38:40 2007 +0000 @@ -366,7 +366,7 @@ dialog = g_new0(PidginPrivacyDialog, 1); - dialog->win = pidgin_create_window(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", FALSE); + dialog->win = pidgin_create_window(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", TRUE); g_signal_connect(G_OBJECT(dialog->win), "delete_event", G_CALLBACK(destroy_cb), dialog); diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/gtksavedstatuses.c Mon Jun 25 21:38:40 2007 +0000 @@ -658,17 +658,16 @@ G_CALLBACK(status_window_close_cb), dialog); purple_signal_connect(purple_savedstatuses_get_handle(), - "savedstatus-changed", dialog, + "savedstatus-changed", status_window, PURPLE_CALLBACK(current_status_changed), dialog); - purple_signal_connect(purple_savedstatuses_get_handle(), - "savedstatus-added", dialog, + "savedstatus-added", status_window, PURPLE_CALLBACK(saved_status_updated_cb), dialog); purple_signal_connect(purple_savedstatuses_get_handle(), - "savedstatus-deleted", dialog, + "savedstatus-deleted", status_window, PURPLE_CALLBACK(saved_status_updated_cb), dialog); purple_signal_connect(purple_savedstatuses_get_handle(), - "savedstatus-modified", dialog, + "savedstatus-modified", status_window, PURPLE_CALLBACK(saved_status_updated_cb), dialog); gtk_widget_show_all(win); @@ -685,6 +684,7 @@ purple_request_close_with_handle(status_window); purple_notify_close_with_handle(status_window); + purple_signals_disconnect_by_handle(status_window); g_free(status_window); status_window = NULL; } @@ -1140,7 +1140,7 @@ if (edit) dialog->original_title = g_strdup(purple_savedstatus_get_title(saved_status)); - dialog->window = win = pidgin_create_window (_("Status"), PIDGIN_HIG_BORDER, "status", FALSE) ; + dialog->window = win = pidgin_create_window(_("Status"), PIDGIN_HIG_BORDER, "status", TRUE); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(status_editor_destroy_cb), dialog); @@ -1475,7 +1475,7 @@ dialog->account = account; tmp = g_strdup_printf(_("Status for %s"), purple_account_get_username(account)); - dialog->window = win = pidgin_create_window(tmp, PIDGIN_HIG_BORDER, "substatus", FALSE) ; + dialog->window = win = pidgin_create_window(tmp, PIDGIN_HIG_BORDER, "substatus", TRUE); g_free(tmp); g_signal_connect(G_OBJECT(win), "delete_event", @@ -1520,7 +1520,7 @@ /* Status mesage */ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); label = gtk_label_new_with_mnemonic(_("_Message:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/gtkstatusbox.c Mon Jun 25 21:38:40 2007 +0000 @@ -1016,10 +1016,10 @@ } } -static void -pidgin_status_box_regenerate(PidginStatusBox *status_box) +static gboolean +pidgin_status_box_regenerate_real(PidginStatusBox *status_box) { - GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4; + GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4, *pixbuf5; GtkIconSize icon_size; icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL); @@ -1049,15 +1049,19 @@ icon_size, "PidginStatusBox"); pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_INVISIBLE, icon_size, "PidginStatusBox"); + pixbuf5 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_BUSY, + icon_size, "PidginStatusBox"); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf, _("Available"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf2, _("Away"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AWAY)); + pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf5, _("Do not disturb"), NULL, GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf4, _("Invisible"), NULL, GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf3, _("Offline"), NULL, GINT_TO_POINTER(PURPLE_STATUS_OFFLINE)); if (pixbuf2) g_object_unref(G_OBJECT(pixbuf2)); if (pixbuf3) g_object_unref(G_OBJECT(pixbuf3)); if (pixbuf4) g_object_unref(G_OBJECT(pixbuf4)); + if (pixbuf5) g_object_unref(G_OBJECT(pixbuf5)); } add_popular_statuses(status_box); @@ -1077,11 +1081,21 @@ } gtk_tree_view_set_model(GTK_TREE_VIEW(status_box->tree_view), GTK_TREE_MODEL(status_box->dropdown_store)); gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN); + + return FALSE; +} + +static void +pidgin_status_box_regenerate(PidginStatusBox *status_box) +{ + /* we have to do this in a timeout, so we avoid recursing + * to infinity (and beyond) */ + purple_timeout_add(0, (GSourceFunc)pidgin_status_box_regenerate_real, status_box); } static gboolean combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml) { - pidgin_status_box_popup(PIDGIN_STATUS_BOX(w)); + pidgin_status_box_popup(PIDGIN_STATUS_BOX(w)); return TRUE; } diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/pidginstock.c --- a/pidgin/pidginstock.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/pidginstock.c Mon Jun 25 21:38:40 2007 +0000 @@ -169,10 +169,8 @@ { PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } -/* Uncomment me after 2.0.2! - * { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } - */ + { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } }; static gchar * diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/pidginstock.h --- a/pidgin/pidginstock.h Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/pidginstock.h Mon Jun 25 21:38:40 2007 +0000 @@ -137,9 +137,7 @@ #define PIDGIN_STOCK_TRAY_OFFLINE "pidgin-tray-offline" #define PIDGIN_STOCK_TRAY_CONNECT "pidgin-tray-connect" #define PIDGIN_STOCK_TRAY_PENDING "pidgin-tray-pending" -/* Uncomment me after 2.0.2! - * #define PIDGIN_STOCK_TRAY_EMAIL "pidgin-tray-email" - */ +#define PIDGIN_STOCK_TRAY_EMAIL "pidgin-tray-email" /*@}*/ diff -r 3c6bf77bf7c4 -r 22838745420a pidgin/plugins/gtkbuddynote.c --- a/pidgin/plugins/gtkbuddynote.c Sat Jun 23 20:34:07 2007 +0000 +++ b/pidgin/plugins/gtkbuddynote.c Mon Jun 25 21:38:40 2007 +0000 @@ -30,8 +30,8 @@ if (full) { const gchar *note = purple_blist_node_get_string(node, "notes"); - if (note != NULL) { - g_string_append_printf(text, _("\nBuddy Note: %s"), + if ((note != NULL) && (*note != '\0')) { + g_string_append_printf(text, _("\nBuddy Note: %s"), note); } } @@ -94,6 +94,7 @@ check_for_buddynote(gpointer data) { PurplePlugin *buddynote = NULL; + PurplePlugin *plugin = (PurplePlugin *)data; buddynote = purple_plugins_find_with_id("core-plugin_pack-buddynote"); @@ -108,6 +109,18 @@ info.dependencies = g_list_append(info.dependencies, "core-plugin_pack-buddynote"); + + /* If non-gtk buddy note plugin is loaded, but we are not, then load + * ourselves, otherwise people upgrading from pre-gtkbuddynote days + * will not have 'Buddy Notes' showing as loaded in the plugins list. + * We also trigger a save on the list of plugins because it's not been + * loaded through the UI. */ + if (purple_plugin_is_loaded(buddynote) && + !purple_plugin_is_loaded(plugin)) { + purple_plugin_load(plugin); + pidgin_plugins_save(); + } + } else { info.flags = PURPLE_PLUGIN_FLAG_INVISIBLE; }