# HG changeset patch # User John Bailey # Date 1257011574 0 # Node ID e3206d6da6c74d0b3fdec598bb11cd159938af15 # Parent a78a44f0cdcdc3f4d55e13341673bc708fef786c# Parent 96f0f6af5da2e537d2d1d03b8a10016a0da1d7b7 propagate from branch 'im.pidgin.pidgin' (head bc551a0f3f61b07c37e8677925b1aeae91e849be) to branch 'im.pidgin.pidgin.next.minor' (head 6d87b28fb7d202e9e5cf6700c99d9f140fdcd245) diff -r a78a44f0cdcd -r e3206d6da6c7 ChangeLog --- a/ChangeLog Sat Oct 31 17:49:11 2009 +0000 +++ b/ChangeLog Sat Oct 31 17:52:54 2009 +0000 @@ -22,10 +22,14 @@ to announce the list of loaded plugins (in both Finch and Pidgin). * Fix building the GnuTLS plugin with older versions of GnuTLS. * Fix DNS TXT query resolution. + * Always rejoin open chats after an account reconnects. MSN: * Don't forget display names for buddies. * Fix a random crash that might occur when idle. + * Fix more FQY 240 connection errors. + * Fix a crash that could occur when adding a buddy. + * Fix an occasional crash when sending message to an offline user. XMPP: * Users connecting to Google Talk now have an "Initiate Chat" context menu @@ -52,6 +56,8 @@ * The userlist in a multiuser chat can be styled via gtkrc by using the widget name "pidgin_conv_userlist". (Heiko Schmitt) * Add a hold button to the media window. + * Tooltips for custom smileys should work now. + * Users with unread messages are again bolded in the Buddy List. version 2.6.3 (10/16/2009): General: diff -r a78a44f0cdcd -r e3206d6da6c7 autogen.sh --- a/autogen.sh Sat Oct 31 17:49:11 2009 +0000 +++ b/autogen.sh Sat Oct 31 17:52:54 2009 +0000 @@ -83,7 +83,7 @@ OUTPUT=`mktemp autogen-XXXXXX` - printf "%s" "running ${CMD} ${@}... " + printf "running %s %s... " ${CMD} "$*" ${CMD} ${@} >${OUTPUT} 2>&1 if [ $? != 0 ] ; then @@ -99,9 +99,17 @@ fi } +cleanup () { + rm -f autogen-?????? + echo + exit 2 +} + ############################################################################### # We really start here, yes, very sneaky! ############################################################################### +trap cleanup 2 + FIGLET=`which figlet 2> /dev/null` if [ x"${FIGLET}" != x"" ] ; then ${FIGLET} -f small ${PACKAGE} @@ -143,7 +151,7 @@ run_or_die ${INTLTOOLIZE} ${INTLTOOLIZE_FLAGS:-"-c -f --automake"} # This call to sed is needed to work around an annoying bug in intltool 0.40.6 # See http://developer.pidgin.im/ticket/9520 for details -run_or_die ${SED} "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" -i po/Makefile.in.in +run_or_die ${SED} -i.bak -e "s:'\^\$\$lang\$\$':\^\$\$lang\$\$:g" po/Makefile.in.in run_or_die ${ACLOCAL} ${ACLOCAL_FLAGS:-"-I m4macros"} run_or_die ${AUTOHEADER} ${AUTOHEADER_FLAGS} run_or_die ${AUTOMAKE} ${AUTOMAKE_FLAGS:-"-a -c --gnu"} diff -r a78a44f0cdcd -r e3206d6da6c7 finch/gntconn.c --- a/finch/gntconn.c Sat Oct 31 17:49:11 2009 +0000 +++ b/finch/gntconn.c Sat Oct 31 17:52:54 2009 +0000 @@ -107,7 +107,6 @@ { FinchAutoRecon *info; PurpleAccount *account = purple_connection_get_account(gc); - GList *list; if (!purple_connection_error_is_fatal(reason)) { info = g_hash_table_lookup(hash, account); @@ -144,21 +143,6 @@ g_free(secondary); purple_account_set_enabled(account, FINCH_UI, FALSE); } - - /* If we have any open chats, we probably want to rejoin when we get back online. */ - list = purple_get_chats(); - while (list) { - PurpleConversation *conv = list->data; - list = list->next; - if (purple_conversation_get_account(conv) != account || - purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) - continue; - purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); - purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " - "longer in this chat. You will be automatically rejoined in the chat when " - "the account reconnects."), - PURPLE_MESSAGE_SYSTEM, time(NULL)); - } } static void diff -r a78a44f0cdcd -r e3206d6da6c7 finch/gntconv.c --- a/finch/gntconv.c Sat Oct 31 17:49:11 2009 +0000 +++ b/finch/gntconv.c Sat Oct 31 17:52:54 2009 +0000 @@ -367,6 +367,28 @@ } } +static void +account_signing_off(PurpleConnection *gc) +{ + GList *list = purple_get_chats(); + PurpleAccount *account = purple_connection_get_account(gc); + + /* We are about to sign off. See which chats we are currently in, and mark + * them for rejoin on reconnect. */ + while (list) { + PurpleConversation *conv = list->data; + if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) && + purple_conversation_get_account(conv) == account) { + purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); + purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " + "longer in this chat. You will be automatically rejoined in the chat when " + "the account reconnects."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + } + list = list->next; + } +} + static gpointer finch_conv_get_handle(void) { @@ -642,8 +664,25 @@ create_conv_from_userlist(GntWidget *widget, FinchConv *fc) { PurpleAccount *account = purple_conversation_get_account(fc->active_conv); - char *name = gnt_tree_get_selection_data(GNT_TREE(widget)); - purple_conversation_new(PURPLE_CONV_TYPE_IM, account, name); + PurpleConnection *gc = purple_account_get_connection(account); + PurplePluginProtocolInfo *prpl_info = NULL; + char *name, *realname; + + if (!gc) { + purple_conversation_write(fc->active_conv, NULL, _("You are not connected."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + return; + } + + name = gnt_tree_get_selection_data(GNT_TREE(widget)); + + prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); + if (prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_cb_real_name)) + realname = prpl_info->get_cb_real_name(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(fc->active_conv)), name); + else + realname = NULL; + purple_conversation_new(PURPLE_CONV_TYPE_IM, account, realname ? realname : name); + g_free(realname); } static void @@ -1433,6 +1472,8 @@ PURPLE_CALLBACK(account_signed_on_off), NULL); purple_signal_connect(purple_connections_get_handle(), "signed-off", finch_conv_get_handle(), PURPLE_CALLBACK(account_signed_on_off), NULL); + purple_signal_connect(purple_connections_get_handle(), "signing-off", finch_conv_get_handle(), + PURPLE_CALLBACK(account_signing_off), NULL); } void finch_conversation_uninit() diff -r a78a44f0cdcd -r e3206d6da6c7 finch/libgnt/gntentry.c --- a/finch/libgnt/gntentry.c Sat Oct 31 17:49:11 2009 +0000 +++ b/finch/libgnt/gntentry.c Sat Oct 31 17:52:54 2009 +0000 @@ -1044,8 +1044,11 @@ snprintf(entry->start, len + 1, "%s", text); entry->end = entry->start + len; - entry->scroll = entry->start + scroll; - entry->cursor = entry->end - cursor; + if ((entry->scroll = entry->start + scroll) > entry->end) + entry->scroll = entry->end; + + if ((entry->cursor = entry->end - cursor) > entry->end) + entry->cursor = entry->end; if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED)) entry_redraw(GNT_WIDGET(entry)); diff -r a78a44f0cdcd -r e3206d6da6c7 finch/libgnt/gnttextview.c --- a/finch/libgnt/gnttextview.c Sat Oct 31 17:49:11 2009 +0000 +++ b/finch/libgnt/gnttextview.c Sat Oct 31 17:52:54 2009 +0000 @@ -67,6 +67,12 @@ static void reset_text_view(GntTextView *view); +static gboolean +text_view_contains(GntTextView *view, const char *str) +{ + return (str >= view->string->str && str < view->string->str + view->string->len); +} + static void gnt_text_view_draw(GntWidget *widget) { @@ -109,7 +115,7 @@ char back = *end; chtype fl = seg->flags; *end = '\0'; - if (select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) { + if (select_start && select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) { fl |= A_REVERSE; wattrset(widget->window, fl); wprintw(widget->window, "%s", (view->string->str + seg->start)); @@ -326,9 +332,10 @@ select_start = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y); g_timeout_add(500, too_slow, NULL); } else if (event == GNT_MOUSE_UP) { - if (select_start) { + GntTextView *view = GNT_TEXT_VIEW(widget); + if (text_view_contains(view, select_start)) { GString *clip; - select_end = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y); + select_end = gnt_text_view_get_p(view, x - widget->priv.x, y - widget->priv.y); if (select_end < select_start) { gchar *t = select_start; select_start = select_end; @@ -336,7 +343,7 @@ } if (select_start == select_end) { if (double_click) { - clip = select_word_text(GNT_TEXT_VIEW(widget), select_start); + clip = select_word_text(view, select_start); double_click = FALSE; } else { double_click = TRUE; diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/Makefile.am --- a/libpurple/Makefile.am Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/Makefile.am Sat Oct 31 17:52:54 2009 +0000 @@ -32,7 +32,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = purple.pc -SUBDIRS = $(GCONF_DIR) plugins protocols tests . example +SUBDIRS = $(GCONF_DIR) plugins protocols . tests example purple_coresources = \ account.c \ diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/account.c --- a/libpurple/account.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/account.c Sat Oct 31 17:52:54 2009 +0000 @@ -1050,6 +1050,16 @@ if(account->system_log) purple_log_free(account->system_log); + while (account->deny) { + g_free(account->deny->data); + account->deny = g_slist_delete_link(account->deny, account->deny); + } + + while (account->permit) { + g_free(account->permit->data); + account->permit = g_slist_delete_link(account->permit, account->permit); + } + priv = PURPLE_ACCOUNT_GET_PRIVATE(account); PURPLE_DBUS_UNREGISTER_POINTER(priv->current_error); if (priv->current_error) { diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/cipher.c --- a/libpurple/cipher.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/cipher.c Sat Oct 31 17:52:54 2009 +0000 @@ -50,10 +50,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ -#include -#include -#include - #include "internal.h" #include "cipher.h" #include "dbus-maybe.h" diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/plugins/perl/perl-handlers.c --- a/libpurple/plugins/perl/perl-handlers.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/plugins/perl/perl-handlers.c Sat Oct 31 17:52:54 2009 +0000 @@ -649,6 +649,7 @@ static void destroy_cmd_handler(PurplePerlCmdHandler *handler) { + purple_cmd_unregister(handler->id); cmd_handlers = g_slist_remove(cmd_handlers, handler); if (handler->callback != NULL) @@ -705,7 +706,6 @@ return; } - purple_cmd_unregister(id); destroy_cmd_handler(handler); } diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/JEPS --- a/libpurple/protocols/jabber/JEPS Sat Oct 31 17:49:11 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -0045: IN PROGRESS - Multi-User Chat -0047: IN PROGRESS - In-Band Bytestreams -0060: NEED - Pub-Sub -0071: AWAITING FINAL SPEC - XHTML-IM -0073: NEED - Basic IM Protocol Suite -0080: NEED (Do we?) - Geographic Location Information -0084: NEED - User Avatars in Jabber -0085: NEED - Chat State Notifications -0089: WATCH - Generic Alerts -0093: NEED - Roster Item Exchange -0100: NEED - Gateway Interaction (Transports) -0115: WATCH - Client Capabilities -0117: NEED - Intermediate IM Protocol Suite - diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/XEPS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/jabber/XEPS Sat Oct 31 17:52:54 2009 +0000 @@ -0,0 +1,4 @@ +0060: NEED + Pub-Sub +0080: NEED (Do we?) + Geographic Location Information diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/caps.c --- a/libpurple/protocols/jabber/caps.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/caps.c Sat Oct 31 17:52:54 2009 +0000 @@ -975,7 +975,7 @@ g_free(js->caps_hash); js->caps_hash = jabber_caps_calculate_hash(&info, "sha1"); g_list_free(info.identities); - g_list_free(features); + g_list_free(info.features); } const gchar* jabber_caps_get_own_hash(JabberStream *js) diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/chat.c --- a/libpurple/protocols/jabber/chat.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/chat.c Sat Oct 31 17:52:54 2009 +0000 @@ -692,11 +692,11 @@ } -void jabber_chat_change_nick(JabberChat *chat, const char *nick) +gboolean jabber_chat_change_nick(JabberChat *chat, const char *nick) { xmlnode *presence; char *full_jid; - PurplePresence *gpresence; + PurpleAccount *account; PurpleStatus *status; JabberBuddyState state; char *msg; @@ -706,11 +706,11 @@ purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "", _("Nick changing not supported in non-MUC chatrooms"), PURPLE_MESSAGE_SYSTEM, time(NULL)); - return; + return FALSE; } - gpresence = purple_account_get_presence(chat->js->gc->account); - status = purple_presence_get_active_status(gpresence); + account = purple_connection_get_account(chat->js->gc); + status = purple_account_get_active_status(account); purple_status_to_jabber(status, &state, &msg, &priority); @@ -722,6 +722,8 @@ jabber_send(chat->js, presence); xmlnode_free(presence); + + return TRUE; } void jabber_chat_part(JabberChat *chat, const char *msg) diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/chat.h --- a/libpurple/protocols/jabber/chat.h Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/chat.h Sat Oct 31 17:52:54 2009 +0000 @@ -89,7 +89,7 @@ void jabber_chat_register(JabberChat *chat); void jabber_chat_change_topic(JabberChat *chat, const char *topic); void jabber_chat_set_topic(PurpleConnection *gc, int id, const char *topic); -void jabber_chat_change_nick(JabberChat *chat, const char *nick); +gboolean jabber_chat_change_nick(JabberChat *chat, const char *nick); void jabber_chat_part(JabberChat *chat, const char *msg); void jabber_chat_track_handle(JabberChat *chat, const char *handle, const char *jid, const char *affiliation, const char *role); diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/google.c --- a/libpurple/protocols/jabber/google.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/google.c Sat Oct 31 17:52:54 2009 +0000 @@ -994,8 +994,9 @@ const char *grt = xmlnode_get_attrib_with_namespace(item, "t", "google:roster"); const char *subscription = xmlnode_get_attrib(item, "subscription"); + const char *ask = xmlnode_get_attrib(item, "ask"); - if (!subscription || !strcmp(subscription, "none")) { + if ((!subscription || !strcmp(subscription, "none")) && !ask) { /* The Google Talk servers will automatically add people from your Gmail address book * with subscription=none. If we see someone with subscription=none, ignore them. */ diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sat Oct 31 17:52:54 2009 +0000 @@ -1825,7 +1825,7 @@ JabberFeature *feature = jabber_features->data; g_free(feature->namespace); g_free(feature); - jabber_features = g_list_remove_link(jabber_features, jabber_features); + jabber_features = g_list_delete_link(jabber_features, jabber_features); } } @@ -1862,7 +1862,7 @@ g_free(id->lang); g_free(id->name); g_free(id); - jabber_identities = g_list_remove_link(jabber_identities, jabber_identities); + jabber_identities = g_list_delete_link(jabber_identities, jabber_identities); } } @@ -2606,8 +2606,15 @@ if(!chat || !args || !args[0]) return PURPLE_CMD_RET_FAILED; - jabber_chat_change_nick(chat, args[0]); - return PURPLE_CMD_RET_OK; + if (!jabber_resourceprep_validate(args[0])) { + *error = g_strdup(_("Invalid nickname")); + return PURPLE_CMD_RET_FAILED; + } + + if (jabber_chat_change_nick(chat, args[0])) + return PURPLE_CMD_RET_OK; + else + return PURPLE_CMD_RET_FAILED; } static PurpleCmdRet jabber_cmd_chat_part(PurpleConversation *conv, diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/jabber/roster.c --- a/libpurple/protocols/jabber/roster.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/jabber/roster.c Sat Oct 31 17:52:54 2009 +0000 @@ -72,7 +72,7 @@ const char *alias, GSList *groups) { GSList *buddies, *l; - GSList *pool = NULL; + PurpleAccount *account = purple_connection_get_account(js->gc); buddies = purple_find_buddies(js->gc->account, jid); @@ -117,25 +117,14 @@ groups = g_slist_delete_link(groups, l); } else { /* This buddy isn't in the group on the server anymore */ - pool = g_slist_prepend(pool, b); + purple_debug_info("jabber", "jabber_roster_parse(): Removing %s " + "from group '%s' on the local list\n", + purple_buddy_get_name(b), + purple_group_get_name(g)); + purple_blist_remove_buddy(b); } } - if (pool) { - GString *tmp = g_string_new(NULL); - GSList *list = pool; - for ( ; list; list = list->next) { - tmp = g_string_append(tmp, - purple_group_get_name(purple_buddy_get_group(list->data))); - if (list->next) - tmp = g_string_append(tmp, ", "); - } - - purple_debug_info("jabber", "jabber_roster_parse(): Removing %s from " - "groups: %s\n", jid, tmp->str); - g_string_free(tmp, TRUE); - } - if (groups) { char *tmp = roster_groups_join(groups); purple_debug_info("jabber", "jabber_roster_parse(): Adding %s to " @@ -145,17 +134,7 @@ while(groups) { PurpleGroup *g = purple_find_group(groups->data); - PurpleBuddy *b = NULL; - - /* If there are buddies we would otherwise delete, move them to - * the new group (instead of deleting them below) - */ - if (pool) { - b = pool->data; - pool = g_slist_delete_link(pool, pool); - } else { - b = purple_buddy_new(js->gc->account, jid, alias); - } + PurpleBuddy *b = purple_buddy_new(account, jid, alias); if(!g) { g = purple_group_new(groups->data); @@ -169,14 +148,6 @@ groups = g_slist_delete_link(groups, groups); } - /* Remove this person from all the groups they're no longer in on the - * server */ - while (pool) { - PurpleBuddy *b = pool->data; - purple_blist_remove_buddy(b); - pool = g_slist_delete_link(pool, pool); - } - g_slist_free(buddies); } diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/contact.c --- a/libpurple/protocols/msn/contact.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/contact.c Sat Oct 31 17:52:54 2009 +0000 @@ -362,7 +362,7 @@ char *display_text; passport = xmlnode_get_data(xmlnode_get_child(member, node)); - if (!purple_email_is_valid(passport)) { + if (!msn_email_is_valid(passport)) { g_free(passport); return; } @@ -765,7 +765,7 @@ if (passport == NULL) continue; - if (!purple_email_is_valid(passport)) + if (!msn_email_is_valid(passport)) continue; if ((displayName = xmlnode_get_child(contactInfo, "displayName"))) @@ -1232,8 +1232,13 @@ if (user->invite_message) { char *tmp; body = g_markup_escape_text(user->invite_message, -1); - tmp = g_markup_escape_text(purple_connection_get_display_name(session->account->gc), -1); + + /* Ignore the cast, we treat it as const anyway. */ + tmp = (char *)purple_connection_get_display_name(session->account->gc); + tmp = tmp ? g_markup_escape_text(tmp, -1) : g_strdup(""); + invite = g_strdup_printf(MSN_CONTACT_INVITE_MESSAGE_XML, body, tmp); + g_free(body); g_free(tmp); diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/msn.c --- a/libpurple/protocols/msn/msn.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/msn.c Sat Oct 31 17:52:54 2009 +0000 @@ -118,6 +118,29 @@ return buf; } +gboolean +msn_email_is_valid(const char *passport) +{ + if (purple_email_is_valid(passport)) { + /* Special characters aren't allowed in domains, so only go to '@' */ + while (*passport != '@') { + if (*passport == '/') + return FALSE; + else if (*passport == '?') + return FALSE; + else if (*passport == '=') + return FALSE; + /* MSN also doesn't like colons, but that's checked already */ + + passport++; + } + + return TRUE; + } + + return FALSE; +} + static gboolean msn_send_attention(PurpleConnection *gc, const char *username, guint type) { @@ -1511,7 +1534,7 @@ bname = purple_buddy_get_name(buddy); - if (!purple_email_is_valid(bname)) { + if (!msn_email_is_valid(bname)) { gchar *buf; buf = g_strdup_printf(_("Unable to add the buddy %s because the username is invalid. Usernames must be valid email addresses."), bname); if (!purple_conv_present_error(bname, purple_connection_get_account(gc), buf)) diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/msn.h --- a/libpurple/protocols/msn/msn.h Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/msn.h Sat Oct 31 17:52:54 2009 +0000 @@ -133,6 +133,7 @@ ((MSN_CLIENT_ID_VERSION << 24) | \ (MSN_CLIENT_ID_CAPABILITIES)) +gboolean msn_email_is_valid(const char *passport); void msn_act_id(PurpleConnection *gc, const char *entry); void msn_send_privacy(PurpleConnection *gc); void msn_send_im_message(MsnSession *session, MsnMessage *msg); diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/notification.c --- a/libpurple/protocols/msn/notification.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/notification.c Sat Oct 31 17:52:54 2009 +0000 @@ -670,7 +670,7 @@ "User %s is on both Allow and Block list; " "removing from Allow list.\n", user->passport); - msn_userlist_rem_buddy_from_list(session->userlist, user->passport, MSN_LIST_AL); + msn_user_unset_op(user, MSN_LIST_AL_OP); } if (user->networkid != MSN_NETWORK_UNKNOWN) { @@ -840,17 +840,48 @@ MsnSession *session; PurpleAccount *account; PurpleConnection *gc; - char *adl = g_strndup(payload, len); - char *reason = g_strdup_printf(_("Unknown error (%d): %s"), - GPOINTER_TO_INT(cmd->payload_cbdata), adl); - g_free(adl); + int error = GPOINTER_TO_INT(cmd->payload_cbdata); session = cmdproc->session; account = session->account; gc = purple_account_get_connection(account); - purple_notify_error(gc, NULL, _("Unable to add user"), reason); - g_free(reason); + if (error == 241) { + /* khc: some googling suggests that error 241 means the buddy is somehow + in the local list, but not the server list, and that we should add + those buddies to the addressbook. For now I will just notify the user + about the raw payload, because I am lazy */ + xmlnode *adl = xmlnode_from_str(payload, len); + GString *emails = g_string_new(NULL); + + xmlnode *domain = xmlnode_get_child(adl, "d"); + while (domain) { + const char *domain_str = xmlnode_get_attrib(domain, "n"); + xmlnode *contact = xmlnode_get_child(domain, "c"); + while (contact) { + g_string_append_printf(emails, "%s@%s\n", + xmlnode_get_attrib(contact, "n"), domain_str); + contact = xmlnode_get_next_twin(contact); + } + domain = xmlnode_get_next_twin(domain); + } + + purple_notify_error(gc, NULL, + _("The following users are missing from your addressbook"), + emails->str); + g_string_free(emails, TRUE); + xmlnode_free(adl); + } + else + { + char *adl = g_strndup(payload, len); + char *reason = g_strdup_printf(_("Unknown error (%d): %s"), + error, adl); + g_free(adl); + + purple_notify_error(gc, NULL, _("Unable to add user"), reason); + g_free(reason); + } } static void @@ -878,50 +909,49 @@ } static void -adl_241_error_cmd_post(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, - size_t len) +rml_error_parse(MsnCmdProc *cmdproc, MsnCommand *cmd, char *payload, size_t len) { - /* khc: some googling suggests that error 241 means the buddy is somehow - in the local list, but not the server list, and that we should add - those buddies to the addressbook. For now I will just notify the user - about the raw payload, because I am lazy */ MsnSession *session; PurpleAccount *account; PurpleConnection *gc; - xmlnode *adl; - xmlnode *domain; - GString *emails; + char *adl, *reason; + int error = GPOINTER_TO_INT(cmd->payload_cbdata); session = cmdproc->session; account = session->account; gc = purple_account_get_connection(account); - adl = xmlnode_from_str(payload, len); - emails = g_string_new(NULL); + adl = g_strndup(payload, len); + reason = g_strdup_printf(_("Unknown error (%d): %s"), + error, adl); + g_free(adl); - domain = xmlnode_get_child(adl, "d"); - while (domain) { - const char *domain_str = xmlnode_get_attrib(domain, "n"); - xmlnode *contact = xmlnode_get_child(domain, "c"); - while (contact) { - g_string_append_printf(emails, "%s@%s\n", - xmlnode_get_attrib(contact, "n"), domain_str); - contact = xmlnode_get_next_twin(contact); - } - domain = xmlnode_get_next_twin(domain); - } - - purple_notify_error(gc, NULL, - _("The following users are missing from your addressbook"), emails->str); - g_string_free(emails, TRUE); - xmlnode_free(adl); + purple_notify_error(gc, NULL, _("Unable to remove user"), reason); + g_free(reason); } static void -adl_241_error_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd) +rml_error(MsnCmdProc *cmdproc, MsnTransaction *trans, int error) { - cmdproc->last_cmd->payload_cb = adl_241_error_cmd_post; - cmd->payload_len = atoi(cmd->params[1]); + MsnSession *session; + PurpleAccount *account; + PurpleConnection *gc; + MsnCommand *cmd = cmdproc->last_cmd; + + session = cmdproc->session; + account = session->account; + gc = purple_account_get_connection(account); + + purple_debug_error("msn", "RML error\n"); + if (cmd->param_count > 1) { + cmd->payload_cb = rml_error_parse; + cmd->payload_len = atoi(cmd->params[1]); + cmd->payload_cbdata = GINT_TO_POINTER(error); + } else { + char *reason = g_strdup_printf(_("Unknown error (%d)"), error); + purple_notify_error(gc, NULL, _("Unable to remove user"), reason); + g_free(reason); + } } static void @@ -1068,7 +1098,17 @@ /* Where'd this come from? */ return; - if (cmd->param_count == 7) { + if (cmd->param_count == 8) { + /* Yahoo! Buddy, looks like */ + networkid = atoi(cmd->params[3]); + friendly = g_strdup(purple_url_decode(cmd->params[4])); + clientid = strtoul(cmd->params[5], NULL, 10); + + /* cmd->params[7] seems to be a URL to a Yahoo! icon: + https://sec.yimg.com/i/us/nt/b/purpley.1.0.png + ... and it's purple, HAH! + */ + } else if (cmd->param_count == 7) { /* MSNP14+ with Display Picture object */ networkid = atoi(cmd->params[3]); friendly = g_strdup(purple_url_decode(cmd->params[4])); @@ -2095,9 +2135,8 @@ msn_table_add_cmd(cbs_table, "fallback", "XFR", xfr_cmd); - msn_table_add_cmd(cbs_table, NULL, "241", adl_241_error_cmd); - msn_table_add_error(cbs_table, "ADL", adl_error); + msn_table_add_error(cbs_table, "RML", rml_error); msn_table_add_error(cbs_table, "FQY", fqy_error); msn_table_add_error(cbs_table, "USR", usr_error); diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/oim.c --- a/libpurple/protocols/msn/oim.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/oim.c Sat Oct 31 17:52:54 2009 +0000 @@ -153,7 +153,7 @@ gpointer cb_data; } MsnOimRequestData; -static void msn_oim_request_helper(MsnOimRequestData *data); +static gboolean msn_oim_request_helper(MsnOimRequestData *data); static void msn_oim_request_cb(MsnSoapMessage *request, MsnSoapMessage *response, @@ -202,7 +202,7 @@ g_free(data); } -static void +static gboolean msn_oim_request_helper(MsnOimRequestData *data) { MsnSession *session = data->oim->session; @@ -224,13 +224,13 @@ const char *msn_p; token = msn_nexus_get_token(session->nexus, MSN_AUTH_MESSENGER_WEB); - g_return_if_fail(token != NULL); + g_return_val_if_fail(token != NULL, FALSE); msn_t = g_hash_table_lookup(token, "t"); msn_p = g_hash_table_lookup(token, "p"); - g_return_if_fail(msn_t != NULL); - g_return_if_fail(msn_p != NULL); + g_return_val_if_fail(msn_t != NULL, FALSE); + g_return_val_if_fail(msn_p != NULL, FALSE); passport = xmlnode_get_child(data->body, "Header/PassportCookie"); xml_t = xmlnode_get_child(passport, "t"); @@ -248,6 +248,8 @@ msn_soap_message_new(data->action, xmlnode_copy(data->body)), data->host, data->url, FALSE, msn_oim_request_cb, data); + + return FALSE; } diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/msn/userlist.c --- a/libpurple/protocols/msn/userlist.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/msn/userlist.c Sat Oct 31 17:52:54 2009 +0000 @@ -539,7 +539,7 @@ purple_debug_info("msn", "Add user: %s to group: %s\n", who, new_group_name); - if (!purple_email_is_valid(who)) + if (!msn_email_is_valid(who)) { /* only notify the user about problems adding to the friends list * maybe we should do something else for other lists, but it probably diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/protocols/yahoo/libymsg.c --- a/libpurple/protocols/yahoo/libymsg.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/protocols/yahoo/libymsg.c Sat Oct 31 17:52:54 2009 +0000 @@ -154,6 +154,7 @@ gboolean unicode = FALSE; char *message = NULL; YahooFederation fed = YAHOO_FEDERATION_NONE; + char *fedname = NULL; if (pkt->service == YAHOO_SERVICE_LOGOFF && pkt->status == -1) { if (!purple_account_get_remember_password(account)) @@ -194,18 +195,20 @@ break; if (p->key == 241) { fed = strtol(p->value, NULL, 10); + g_free(fedname); switch (fed) { case YAHOO_FEDERATION_MSN: - name = g_strconcat("msn/", name, NULL); + name = fedname = g_strconcat("msn/", name, NULL); break; case YAHOO_FEDERATION_OCS: - name = g_strconcat("ocs/", name, NULL); + name = fedname = g_strconcat("ocs/", name, NULL); break; case YAHOO_FEDERATION_IBM: - name = g_strconcat("ibm/", name, NULL); + name = fedname = g_strconcat("ibm/", name, NULL); break; case YAHOO_FEDERATION_NONE: default: + fedname = NULL; break; } break; @@ -390,6 +393,7 @@ yahoo_update_status(gc, name, f); } + g_free(fedname); } static void yahoo_do_group_check(PurpleAccount *account, GHashTable *ht, const char *name, const char *group) @@ -879,6 +883,7 @@ char *id; char *msg; YahooFederation fed; + char *fed_from; }; static void yahoo_process_sms_message(PurpleConnection *gc, struct yahoo_packet *pkt) @@ -950,9 +955,6 @@ GSList *l = pkt->hash; GSList *list = NULL; struct _yahoo_im *im = NULL; - const char *imv = NULL; - gint val_11 = 0; - char *fed_from = NULL; account = purple_connection_get_account(gc); @@ -963,10 +965,11 @@ if (pair->key == 4 || pair->key == 1) { im = g_new0(struct _yahoo_im, 1); list = g_slist_append(list, im); - im->from = fed_from = pair->value; + im->from = pair->value; im->time = time(NULL); im->utf8 = TRUE; im->fed = YAHOO_FEDERATION_NONE; + im->fed_from = g_strdup(im->from); } if (im && pair->key == 5) im->active_id = pair->value; @@ -985,32 +988,75 @@ } if (im && pair->key == 241) { im->fed = strtol(pair->value, NULL, 10); + g_free(im->fed_from); switch (im->fed) { case YAHOO_FEDERATION_MSN: - fed_from = g_strconcat("msn/",im->from, NULL); + im->fed_from = g_strconcat("msn/",im->from, NULL); break; case YAHOO_FEDERATION_OCS: - fed_from = g_strconcat("ocs/",im->from, NULL); + im->fed_from = g_strconcat("ocs/",im->from, NULL); break; case YAHOO_FEDERATION_IBM: - fed_from = g_strconcat("ibm/",im->from, NULL); + im->fed_from = g_strconcat("ibm/",im->from, NULL); break; case YAHOO_FEDERATION_NONE: default: + im->fed_from = g_strdup(im->from); break; } - purple_debug_info("yahoo", "Message from federated (%d) buddy %s.\n", im->fed, fed_from); + purple_debug_info("yahoo", "Message from federated (%d) buddy %s.\n", im->fed, im->fed_from); } /* peer session id */ - if (pair->key == 11) { - if (im) - val_11 = strtol(pair->value, NULL, 10); + if (im && (pair->key == 11)) { + /* disconnect the peer if connected through p2p and sends wrong value for session id */ + if( (im->fed == YAHOO_FEDERATION_NONE) && (pkt_type == YAHOO_PKT_TYPE_P2P) + && (yd->session_id != strtol(pair->value, NULL, 10)) ) + { + purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im->fed_from); + /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ + g_hash_table_remove(yd->peers, im->fed_from); + g_free(im->fed_from); + g_free(im); + return; /* Not sure whether we should process remaining IMs in this packet */ + } } /* IMV key */ - if (pair->key == 63) + if (im && pair->key == 63) { - imv = pair->value; + /* Check for the Doodle IMV, no IMvironment for federated buddies */ + if (im->from != NULL && im->fed == YAHOO_FEDERATION_NONE) + { + g_hash_table_replace(yd->imvironments, g_strdup(im->from), g_strdup(pair->value)); + + if (strstr(pair->value, "doodle;") != NULL) + { + PurpleWhiteboard *wb; + + if (!purple_privacy_check(account, im->from)) { + purple_debug_info("yahoo", "Doodle request from %s dropped.\n", + im->from); + g_free(im->fed_from); + g_free(im); + return; + } + /* I'm not sure the following ever happens -DAA */ + wb = purple_whiteboard_get_session(account, im->from); + + /* If a Doodle session doesn't exist between this user */ + if(wb == NULL) + { + doodle_session *ds; + wb = purple_whiteboard_create(account, im->from, + DOODLE_STATE_REQUESTED); + ds = wb->proto_data; + ds->imv_key = g_strdup(pair->value); + + yahoo_doodle_command_send_request(gc, im->from, pair->value); + yahoo_doodle_command_send_ready(gc, im->from, pair->value); + } + } + } } if (pair->key == 429) if (im) @@ -1022,63 +1068,19 @@ _("Your Yahoo! message did not get sent."), NULL); } - /* disconnect the peer if connected through p2p and sends wrong value for session id */ - if( (pkt_type == YAHOO_PKT_TYPE_P2P) && (val_11 != yd->session_id) ) { - purple_debug_warning("yahoo","p2p: %s sent us message with wrong session id. Disconnecting p2p connection to peer\n", im ? fed_from : "(im was null)"); - /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */ - if (im) { - g_hash_table_remove(yd->peers, fed_from); - g_free(im); - } - return; - } - - /* TODO: It seems that this check should be per IM, not global */ - /* Check for the Doodle IMV */ - /* no doodle with federated buddies -- assumption??? */ - if (im != NULL && imv!= NULL && im->from != NULL) - { - g_hash_table_replace(yd->imvironments, g_strdup(im->from), g_strdup(imv)); - - if (strstr(imv, "doodle;") != NULL) - { - PurpleWhiteboard *wb; - - if (!purple_privacy_check(account, im->from)) { - purple_debug_info("yahoo", "Doodle request from %s dropped.\n", im->from); - return; - } - - /* I'm not sure the following ever happens -DAA */ - - wb = purple_whiteboard_get_session(account, im->from); - - /* If a Doodle session doesn't exist between this user */ - if(wb == NULL) - { - doodle_session *ds; - wb = purple_whiteboard_create(account, im->from, DOODLE_STATE_REQUESTED); - ds = wb->proto_data; - ds->imv_key = g_strdup(imv); - - yahoo_doodle_command_send_request(gc, im->from, imv); - yahoo_doodle_command_send_ready(gc, im->from, imv); - } - } - } - for (l = list; l; l = l->next) { YahooFriend *f; char *m, *m2; im = l->data; - if (!fed_from || !im->msg) { + if (!im->fed_from || !im->msg) { + g_free(im->fed_from); g_free(im); continue; } - if (!purple_privacy_check(account, fed_from)) { - purple_debug_info("yahoo", "Message from %s dropped.\n", fed_from); + if (!purple_privacy_check(account, im->fed_from)) { + purple_debug_info("yahoo", "Message from %s dropped.\n", im->fed_from); return; } @@ -1116,10 +1118,11 @@ if (!strcmp(m, "")) { char *username; - username = g_markup_escape_text(fed_from, -1); + username = g_markup_escape_text(im->fed_from, -1); purple_prpl_got_attention(gc, username, YAHOO_BUZZ); g_free(username); g_free(m); + g_free(im->fed_from); g_free(im); continue; } @@ -1127,7 +1130,7 @@ m2 = yahoo_codes_to_html(m); g_free(m); - serv_got_im(gc, fed_from, m2, 0, im->time); + serv_got_im(gc, im->fed_from, m2, 0, im->time); g_free(m2); /* Official clients don't share buddy images with federated buddies */ @@ -1140,9 +1143,7 @@ } } - if(im->fed != YAHOO_FEDERATION_NONE) - g_free(fed_from); - + g_free(im->fed_from); g_free(im); } diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/server.c --- a/libpurple/server.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/server.c Sat Oct 31 17:52:54 2009 +0000 @@ -786,14 +786,14 @@ struct chat_invite_data *cid; int plugin_return; + g_return_if_fail(name != NULL); + g_return_if_fail(who != NULL); + account = purple_connection_get_account(gc); - if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->set_permit_deny == NULL) { - /* protocol does not support privacy, handle it ourselves */ - if (!purple_privacy_check(account, who)) { - purple_signal_emit(purple_conversations_get_handle(), "chat-invite-blocked", - account, who, name, message, data); - return; - } + if (!purple_privacy_check(account, who)) { + purple_signal_emit(purple_conversations_get_handle(), "chat-invite-blocked", + account, who, name, message, data); + return; } cid = g_new0(struct chat_invite_data, 1); diff -r a78a44f0cdcd -r e3206d6da6c7 libpurple/theme-loader.c --- a/libpurple/theme-loader.c Sat Oct 31 17:49:11 2009 +0000 +++ b/libpurple/theme-loader.c Sat Oct 31 17:52:54 2009 +0000 @@ -100,6 +100,7 @@ PurpleThemeLoaderPrivate *priv = PURPLE_THEME_LOADER_GET_PRIVATE(loader); g_free(priv->type); + g_free(priv); parent_class->finalize(obj); } diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkblist.c Sat Oct 31 17:52:54 2009 +0000 @@ -4108,6 +4108,12 @@ } } + if (hidden_conv) { + char *tmp = nametext; + nametext = g_strdup_printf("%s", tmp); + g_free(tmp); + } + /* Put it all together */ if ((!aliased || biglist) && (statustext || idletime)) { /* using breaks the status, so it must be seperated into */ diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkconn.c --- a/pidgin/gtkconn.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkconn.c Sat Oct 31 17:52:54 2009 +0000 @@ -142,7 +142,6 @@ { PurpleAccount *account = NULL; PidginAutoRecon *info; - GList *list; account = purple_connection_get_account(gc); info = g_hash_table_lookup(auto_reconns, account); @@ -164,17 +163,6 @@ purple_account_set_enabled(account, PIDGIN_UI, FALSE); } - - /* If we have any open chats, we probably want to rejoin when we get back online. */ - list = purple_get_chats(); - while (list) { - PurpleConversation *conv = list->data; - list = list->next; - if (conv->account != account || - purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) - continue; - purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); - } } static void pidgin_connection_network_connected (void) diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkconv.c Sat Oct 31 17:52:54 2009 +0000 @@ -4256,7 +4256,7 @@ /* Users */ for (; l != NULL; l = l->next) { tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, - &matches, TRUE, ((PurpleConvChatBuddy *)l->data)->name); + &matches, FALSE, ((PurpleConvChatBuddy *)l->data)->name); } @@ -7534,6 +7534,28 @@ } } +static void +account_signing_off(PurpleConnection *gc) +{ + GList *list = purple_get_chats(); + PurpleAccount *account = purple_connection_get_account(gc); + + /* We are about to sign off. See which chats we are currently in, and mark + * them for rejoin on reconnect. */ + while (list) { + PurpleConversation *conv = list->data; + if (!purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) && + purple_conversation_get_account(conv) == account) { + purple_conversation_set_data(conv, "want-to-rejoin", GINT_TO_POINTER(TRUE)); + purple_conversation_write(conv, NULL, _("The account has disconnected and you are no " + "longer in this chat. You will be automatically rejoined in the chat when " + "the account reconnects."), + PURPLE_MESSAGE_SYSTEM, time(NULL)); + } + list = list->next; + } +} + static gboolean update_buddy_status_timeout(PurpleBuddy *buddy) { @@ -8028,6 +8050,8 @@ purple_signal_connect(purple_connections_get_handle(), "signed-off", handle, G_CALLBACK(account_signed_off_cb), GINT_TO_POINTER(PURPLE_CONV_ACCOUNT_OFFLINE)); + purple_signal_connect(purple_connections_get_handle(), "signing-off", handle, + G_CALLBACK(account_signing_off), NULL); purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", handle, G_CALLBACK(received_im_msg_cb), NULL); diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkimhtml.c Sat Oct 31 17:52:54 2009 +0000 @@ -4929,7 +4929,7 @@ It will be destroyed when 'anchor' is destroyed. */ anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free); - g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text); + g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_tiptext", g_strdup(text), g_free); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); /* This catches the expose events generated by animated @@ -4951,7 +4951,8 @@ gtk_container_add(GTK_CONTAINER(ebox), img); gtk_widget_show(img); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", text, g_free); - g_object_set_data(G_OBJECT(anchor), "gtkimhtml_tiptext", text); + g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_tiptext", + g_strdup(text), g_free); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor); } diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkpounce.c --- a/pidgin/gtkpounce.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkpounce.c Sat Oct 31 17:52:54 2009 +0000 @@ -1442,7 +1442,7 @@ * Here we place the protocol name in the pounce dialog to lessen * confusion about what protocol a pounce is for. */ - tmp = g_strdup_printf( + tmp = g_strdup( (events & PURPLE_POUNCE_TYPING) ? _("Started typing") : (events & PURPLE_POUNCE_TYPED) ? diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkprefs.c Sat Oct 31 17:52:54 2009 +0000 @@ -624,7 +624,8 @@ _("The default Pidgin status icon theme")); gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1); g_free(tmp); - g_object_unref(G_OBJECT(pixbuf)); + if (pixbuf) + g_object_unref(G_OBJECT(pixbuf)); purple_theme_manager_for_each_theme(prefs_themes_sort); pref_sound_generate_markup(); diff -r a78a44f0cdcd -r e3206d6da6c7 pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Sat Oct 31 17:49:11 2009 +0000 +++ b/pidgin/gtkstatusbox.c Sat Oct 31 17:52:54 2009 +0000 @@ -79,8 +79,8 @@ static void pidgin_status_box_pulse_typing(PidginStatusBox *status_box); static void pidgin_status_box_refresh(PidginStatusBox *status_box); -static void status_menu_refresh_iter(PidginStatusBox *status_box); -static void pidgin_status_box_regenerate(PidginStatusBox *status_box); +static void status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed); +static void pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed); static void pidgin_status_box_changed(PidginStatusBox *box); static void pidgin_status_box_size_request (GtkWidget *widget, GtkRequisition *requisition); static void pidgin_status_box_size_allocate (GtkWidget *widget, GtkAllocation *allocation); @@ -304,7 +304,7 @@ if (status_box->account == account) update_to_reflect_account_status(status_box, account, newstatus); else if (status_box->token_status_account == account) - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, TRUE); } static gboolean @@ -312,6 +312,7 @@ { if (event->button == 3) { GtkWidget *menu_item; + const char *path; if (box->icon_box_menu) gtk_widget_destroy(box->icon_box_menu); @@ -325,7 +326,8 @@ menu_item = pidgin_new_item_from_stock(box->icon_box_menu, _("Remove"), GTK_STOCK_REMOVE, G_CALLBACK(remove_buddy_icon_cb), box, 0, 0, NULL); - if (purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon") == NULL) + if (!(path = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon")) + || !*path) gtk_widget_set_sensitive(menu_item, FALSE); gtk_menu_popup(GTK_MENU(box->icon_box_menu), NULL, NULL, NULL, NULL, @@ -559,7 +561,7 @@ else statusbox->token_status_account = check_active_accounts_for_identical_statuses(); - pidgin_status_box_regenerate(statusbox); + pidgin_status_box_regenerate(statusbox, TRUE); break; default: @@ -821,7 +823,7 @@ * keyboard signals instead of the changed signal? */ static void -status_menu_refresh_iter(PidginStatusBox *status_box) +status_menu_refresh_iter(PidginStatusBox *status_box, gboolean status_changed) { PurpleSavedStatus *saved_status; PurpleStatusPrimitive primitive; @@ -912,18 +914,15 @@ } else status_box->active_row = NULL; - message = purple_savedstatus_get_message(saved_status); - if (!purple_savedstatus_is_transient(saved_status) || !message || !*message) - { - status_box->imhtml_visible = FALSE; - gtk_widget_hide_all(status_box->vbox); - } - else - { - status_box->imhtml_visible = TRUE; - gtk_widget_show_all(status_box->vbox); + if (status_changed) { + message = purple_savedstatus_get_message(saved_status); /* + * If we are going to hide the imhtml, don't retain the + * message because showing the old message later is + * confusing. If we are going to set the message to a pre-set, + * then we need to do this anyway + * * Suppress the "changed" signal because the status * was changed programmatically. */ @@ -931,12 +930,24 @@ gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml)); gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml)); - gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); + + if (!purple_savedstatus_is_transient(saved_status) || !message || !*message) + { + status_box->imhtml_visible = FALSE; + gtk_widget_hide_all(status_box->vbox); + } + else + { + status_box->imhtml_visible = TRUE; + gtk_widget_show_all(status_box->vbox); + + gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0); + } + gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE); + update_size(status_box); } - update_size(status_box); - /* Stop suppressing the "changed" signal. */ gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE); } @@ -996,50 +1007,50 @@ * statuses and a token account if they do */ static PurpleAccount* check_active_accounts_for_identical_statuses(void) { - PurpleAccount *acct = NULL, *acct2; - GList *tmp, *tmp2, *active_accts = purple_accounts_get_all_active(); - GList *s, *s1, *s2; - - for (tmp = active_accts; tmp; tmp = tmp->next) { - acct = tmp->data; - s = purple_account_get_status_types(acct); - for (tmp2 = tmp->next; tmp2; tmp2 = tmp2->next) { - acct2 = tmp2->data; - - /* Only actually look at the statuses if the accounts use the same prpl */ - if (strcmp(purple_account_get_protocol_id(acct), purple_account_get_protocol_id(acct2))) { - acct = NULL; - break; - } - - s2 = purple_account_get_status_types(acct2); - - s1 = s; - while (s1 && s2) { - PurpleStatusType *st1 = s1->data, *st2 = s2->data; - /* TODO: Are these enough to consider the statuses identical? */ - if (purple_status_type_get_primitive(st1) != purple_status_type_get_primitive(st2) - || strcmp(purple_status_type_get_id(st1), purple_status_type_get_id(st2)) - || strcmp(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) { - acct = NULL; - break; - } - - s1 = s1->next; - s2 = s2->next; - } - - if (s1 != s2) {/* Will both be NULL if matched */ - acct = NULL; + GList *iter, *active_accts = purple_accounts_get_all_active(); + PurpleAccount *acct1 = NULL; + const char *prpl1 = NULL; + + if (active_accts) { + acct1 = active_accts->data; + prpl1 = purple_account_get_protocol_id(acct1); + } else { + /* there's no enabled account */ + return NULL; + } + + /* start at the second account */ + for (iter = active_accts->next; iter; iter = iter->next) { + PurpleAccount *acct2 = iter->data; + GList *s1, *s2; + + if (!g_str_equal(prpl1, purple_account_get_protocol_id(acct2))) { + acct1 = NULL; + break; + } + + for (s1 = purple_account_get_status_types(acct1), + s2 = purple_account_get_status_types(acct2); s1 && s2; + s1 = s1->next, s2 = s2->next) { + PurpleStatusType *st1 = s1->data, *st2 = s2->data; + /* TODO: Are these enough to consider the statuses identical? */ + if (purple_status_type_get_primitive(st1) != purple_status_type_get_primitive(st2) + || strcmp(purple_status_type_get_id(st1), purple_status_type_get_id(st2)) + || strcmp(purple_status_type_get_name(st1), purple_status_type_get_name(st2))) { + acct1 = NULL; break; } } - if (!acct) + + if (s1 != s2) {/* Will both be NULL if matched */ + acct1 = NULL; break; + } } + g_list_free(active_accts); - return acct; + return acct1; } static void @@ -1068,7 +1079,7 @@ } static void -pidgin_status_box_regenerate(PidginStatusBox *status_box) +pidgin_status_box_regenerate(PidginStatusBox *status_box, gboolean status_changed) { GtkIconSize icon_size; @@ -1104,7 +1115,7 @@ pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_CUSTOM, NULL, _("New status..."), NULL, NULL); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_SAVED, NULL, _("Saved statuses..."), NULL, NULL); - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, status_changed); pidgin_status_box_refresh(status_box); } else { @@ -1156,7 +1167,7 @@ update_to_reflect_account_status(status_box, status_box->account, purple_account_get_active_status(status_box->account)); else { - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, TRUE); pidgin_status_box_refresh(status_box); } return TRUE; @@ -1227,7 +1238,7 @@ /* Regenerate the list if it has changed */ if (initial_token_acct != status_box->token_status_account) { - pidgin_status_box_regenerate(status_box); + pidgin_status_box_regenerate(status_box, TRUE); } } @@ -1236,13 +1247,14 @@ current_savedstatus_changed_cb(PurpleSavedStatus *now, PurpleSavedStatus *old, PidginStatusBox *status_box) { /* Make sure our current status is added to the list of popular statuses */ - pidgin_status_box_regenerate(status_box); + pidgin_status_box_regenerate(status_box, TRUE); } static void saved_status_updated_cb(PurpleSavedStatus *status, PidginStatusBox *status_box) { - pidgin_status_box_regenerate(status_box); + pidgin_status_box_regenerate(status_box, + purple_savedstatus_get_current() == status); } static void @@ -1890,7 +1902,7 @@ status_box->token_status_account = check_active_accounts_for_identical_statuses(); cache_pixbufs(status_box); - pidgin_status_box_regenerate(status_box); + pidgin_status_box_regenerate(status_box, TRUE); purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-changed", status_box, @@ -2291,18 +2303,6 @@ pidgin_status_box_refresh(status_box); } -static gboolean -message_changed(const char *one, const char *two) -{ - if (one == NULL && two == NULL) - return FALSE; - - if (one == NULL || two == NULL) - return TRUE; - - return (g_utf8_collate(one, two) != 0); -} - static void activate_currently_selected_status(PidginStatusBox *status_box) { @@ -2353,6 +2353,7 @@ if (status_box->account == NULL) { PurpleStatusType *acct_status_type = NULL; + const char *id = NULL; /* id of acct_status_type */ PurpleStatusPrimitive primitive = GPOINTER_TO_INT(data); /* Global */ /* Save the newly selected status to prefs.xml and status.xml */ @@ -2361,7 +2362,6 @@ if (status_box->token_status_account) { gint active; PurpleStatus *status; - const char *id = NULL; GtkTreePath *path = gtk_tree_row_reference_get_path(status_box->active_row); active = gtk_tree_path_get_indices(path)[0]; @@ -2369,37 +2369,35 @@ status = purple_account_get_active_status(status_box->token_status_account); - acct_status_type = find_status_type_by_index(status_box->token_status_account, active); + acct_status_type = find_status_type_by_index(status_box->token_status_account, active); id = purple_status_type_get_id(acct_status_type); - if (strncmp(id, purple_status_get_id(status), strlen(id)) == 0) + if (g_str_equal(id, purple_status_get_id(status)) && + purple_strequal(message, purple_status_get_attr_string(status, "message"))) { /* Selected status and previous status is the same */ - if (!message_changed(message, purple_status_get_attr_string(status, "message"))) - { - PurpleSavedStatus *ss = purple_savedstatus_get_current(); - /* Make sure that statusbox displays the correct thing. - * It can get messed up if the previous selection was a - * saved status that wasn't supported by this account */ - if ((purple_savedstatus_get_type(ss) == primitive) - && purple_savedstatus_is_transient(ss) - && purple_savedstatus_has_substatuses(ss)) - changed = FALSE; - } + PurpleSavedStatus *ss = purple_savedstatus_get_current(); + /* Make sure that statusbox displays the correct thing. + * It can get messed up if the previous selection was a + * saved status that wasn't supported by this account */ + if ((purple_savedstatus_get_type(ss) == primitive) + && purple_savedstatus_is_transient(ss) + && purple_savedstatus_has_substatuses(ss)) + changed = FALSE; } } else { saved_status = purple_savedstatus_get_current(); if (purple_savedstatus_get_type(saved_status) == primitive && - !purple_savedstatus_has_substatuses(saved_status)) + !purple_savedstatus_has_substatuses(saved_status) && + purple_strequal(purple_savedstatus_get_message(saved_status), message)) { - if (!message_changed(purple_savedstatus_get_message(saved_status), message)) - changed = FALSE; + changed = FALSE; } } if (changed) { - /* Manually find the appropriate transient acct */ + /* Manually find the appropriate transient status */ if (status_box->token_status_account) { GList *iter = purple_savedstatuses_get_all(); GList *tmp, *active_accts = purple_accounts_get_all_active(); @@ -2407,27 +2405,31 @@ for (; iter != NULL; iter = iter->next) { PurpleSavedStatus *ss = iter->data; const char *ss_msg = purple_savedstatus_get_message(ss); + /* find a known transient status that is the same as the + * new selected one */ if ((purple_savedstatus_get_type(ss) == primitive) && purple_savedstatus_is_transient(ss) && purple_savedstatus_has_substatuses(ss) && /* Must have substatuses */ - !message_changed(ss_msg, message)) + purple_strequal(ss_msg, message)) { gboolean found = FALSE; - /* The currently enabled accounts must have substatuses for all the active accts */ + /* this status 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(acct_status_type))) + if (purple_strequal(subtype_status_id, id)) { found = TRUE; + break; + } } } - if (!found) - continue; - saved_status = ss; - break; + + if (found) { + saved_status = ss; + break; + } } } @@ -2470,11 +2472,11 @@ status_type = find_status_type_by_index(status_box->account, active); id = purple_status_type_get_id(status_type); - if (strncmp(id, purple_status_get_id(status), strlen(id)) == 0) + if (g_str_equal(id, purple_status_get_id(status)) && + purple_strequal(message, purple_status_get_attr_string(status, "message"))) { /* Selected status and previous status is the same */ - if (!message_changed(message, purple_status_get_attr_string(status, "message"))) - changed = FALSE; + changed = FALSE; } if (changed) @@ -2564,7 +2566,7 @@ if (status_box->typing == 0) { /* Nothing has changed, so we don't need to do anything */ - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, FALSE); return; } @@ -2622,14 +2624,14 @@ pidgin_status_editor_show(FALSE, purple_savedstatus_is_transient(saved_status) ? saved_status : NULL); - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, FALSE); return; } if (type == PIDGIN_STATUS_BOX_TYPE_SAVED) { pidgin_status_window_show(); - status_menu_refresh_iter(status_box); + status_menu_refresh_iter(status_box, FALSE); return; } } diff -r a78a44f0cdcd -r e3206d6da6c7 po/ca.po --- a/po/ca.po Sat Oct 31 17:49:11 2009 +0000 +++ b/po/ca.po Sat Oct 31 17:52:54 2009 +0000 @@ -33,8 +33,8 @@ msgstr "" "Project-Id-Version: Pidgin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-09-07 18:26-0700\n" -"PO-Revision-Date: 2009-07-26 17:23+0200\n" +"POT-Creation-Date: 2009-10-25 17:57+0100\n" +"PO-Revision-Date: 2009-10-26 09:20+0100\n" "Last-Translator: Josep Puigdemont i Casamajó \n" "Language-Team: Catalan \n" "MIME-Version: 1.0\n" @@ -576,13 +576,6 @@ msgid "Re-enable Account" msgstr "Rehabilita el compte" -msgid "" -"The account has disconnected and you are no longer in this chat. You will be " -"automatically rejoined in the chat when the account reconnects." -msgstr "" -"El compte s'ha desconnectat i ja no sou al xat. Quan es torni a connectar el " -"compte entrareu de nou automàticament al xat." - msgid "No such command." msgstr "No existeix l'ordre." @@ -625,6 +618,13 @@ msgid "You have left this chat." msgstr "Heu sortit d'aquest xat" +msgid "" +"The account has disconnected and you are no longer in this chat. You will be " +"automatically rejoined in the chat when the account reconnects." +msgstr "" +"El compte s'ha desconnectat i ja no sou al xat. Quan es torni a connectar el " +"compte entrareu de nou automàticament al xat." + msgid "Logging started. Future messages in this conversation will be logged." msgstr "" "S'ha iniciat el registre. Es registraran els propers missatges d'aquesta " @@ -661,6 +661,9 @@ msgid "Enable Sounds" msgstr "Habilita els sons" +msgid "You are not connected." +msgstr "No esteu connectat." + msgid " " msgstr " " @@ -670,8 +673,8 @@ msgstr[0] "Llista d'%d usuari:\n" msgstr[1] "Llista de %d usuaris:\n" -msgid "Supported debug options are: version" -msgstr "Les opcions de depuració disponibles són: version" +msgid "Supported debug options are: plugins version" +msgstr "Les opcions de depuració disponibles són: plugins version" msgid "No such command (in this context)." msgstr "L'ordre no existeix (en aquest context)." @@ -977,6 +980,9 @@ msgid "(none)" msgstr "(cap)" +#. XXX: The following expects that finch_notify_message gets called. This +#. * may not always happen, e.g. when another plugin sets its own +#. * notify_message. So tread carefully. msgid "URI" msgstr "URI" @@ -1554,9 +1560,15 @@ "\n" "S'està aconseguint un TinyURL..." -#, fuzzy +#, c-format +msgid "TinyURL for above: %s" +msgstr "Fes un TinyURL d'això d'aquí dalt: %s" + +msgid "Please wait while TinyURL fetches a shorter URL ..." +msgstr "Espreu mentre TinyURL obté una URL més curta..." + msgid "Only create TinyURL for URLs of this length or greater" -msgstr "Crea TinyURL per a URL així de llargues o més" +msgstr "Només crea TinyURL per a URL així de llargues o més" msgid "TinyURL (or other) address prefix" msgstr "Prefix de l'adreça TinyURL (o altra)" @@ -1567,10 +1579,9 @@ msgid "TinyURL plugin" msgstr "Connector TinyURL" -#, fuzzy msgid "When receiving a message with URL(s), use TinyURL for easier copying" msgstr "" -"Quan rebeu missagtes amb URL, feu servir TinyURL per a copiar més fàcilment" +"En rebre missagtes amb URL, s'empra TinyURL perquè sigui més fàcil copiar" msgid "Online" msgstr "En línia" @@ -1676,27 +1687,25 @@ msgid "buddy list" msgstr "llista d'amics" -#, fuzzy msgid "The certificate is self-signed and cannot be automatically checked." -msgstr "" -"No es pot comprovar el certificat que presenta «%s» atès que està auto-signat." - -#, fuzzy -msgid "The root certificate this one claims to be issued by is unknown." -msgstr "El Pidgin no coneix el certificat arrel d'aquest certificat." - -#, fuzzy +msgstr "No es pot comprovar el certificat atès que està auto-signat." + +msgid "" +"The certificate is not trusted because no certificate that can verify it is " +"currently trusted." +msgstr "" +"No es pot confiar en el certificat atès que no hi hi ha cap altre certificat " +"de confiança que el pugui verificar." + msgid "The certificate is not valid yet." -msgstr "La cadena de certificació que presenta %s no és vàlida." - -#, fuzzy +msgstr "El certificat encara no és vàlid." + msgid "The certificate has expired and should not be considered valid." -msgstr "La cadena de certificació que presenta %s no és vàlida." +msgstr "El certificat ha expirat i no s'hauria de considerar vàlid." #. Translators: "domain" refers to a DNS domain (e.g. talk.google.com) -#, fuzzy msgid "The certificate presented is not issued to this domain." -msgstr "La cadena de certificació que presenta %s no és vàlida." +msgstr "El certificat que s'ha presentat no ha estat emès per a aquest domini." msgid "" "You have no database of root certificates, so this certificate cannot be " @@ -1705,17 +1714,14 @@ "Aquest certificat no es pot validar perquè no teniu cap base de dades de " "certificats arrel." -#, fuzzy msgid "The certificate chain presented is invalid." -msgstr "La cadena de certificació que presenta %s no és vàlida." - -#, fuzzy +msgstr "La cadena de certificació que s'ha presentat no és vàlida." + msgid "The certificate has been revoked." -msgstr "Ha finalitzat la trucada." - -#, fuzzy +msgstr "El certificat ha estat revocat." + msgid "An unknown certificate error occurred." -msgstr "Hi ha hagut un error de connexió desconegut: %s." +msgstr "S'ha produït un error desconegut en el certificat." msgid "(DOES NOT MATCH)" msgstr "(NO COINCIDEIX)" @@ -1760,26 +1766,25 @@ msgid "_View Certificate..." msgstr "_Mostra el certificat..." -#, fuzzy, c-format +#, c-format msgid "The certificate for %s could not be validated." -msgstr "La cadena de certificació que presenta %s no és vàlida." +msgstr "No s'ha pogut validar el certificat de %s." # Títol de finestra (josep) #. TODO: Probably wrong. msgid "SSL Certificate Error" msgstr "Error en el certificat SSL" -#, fuzzy msgid "Unable to validate certificate" -msgstr "No s'ha pogut autenticar: %s" - -#, fuzzy, c-format +msgstr "No s'ha pogut certificar" + +#, c-format msgid "" "The certificate claims to be from \"%s\" instead. This could mean that you " "are not connecting to the service you believe you are." msgstr "" -"El certificat de «%s» sembla indicar que és de «%s». Això podria voler dir que " -"us esteu connectant a un servei diferent del que us penseu." +"El certificat indica que és de «%s». Això podria voler dir que us esteu " +"connectant a un servei diferent del que us penseu." #. Make messages #, c-format @@ -1927,6 +1932,10 @@ msgstr "El procés resoledor ha acabat sense respondre la nostra sol·licitud" #, c-format +msgid "Error converting %s to punycode: %d" +msgstr "S'ha produït un error en convertir %s a punycode: %d" + +#, c-format msgid "Thread creation failure: %s" msgstr "S'ha produït un error en crear un fil: %s" @@ -2020,18 +2029,18 @@ msgid "File transfer complete" msgstr "S'ha completat la transferència del fitxer" -#, fuzzy, c-format +#, c-format msgid "You cancelled the transfer of %s" msgstr "Heu cancel·lat la transferència de %s" msgid "File transfer cancelled" msgstr "S'ha cancel·lat la transferència del fitxer" -#, fuzzy, c-format +#, c-format msgid "%s cancelled the transfer of %s" msgstr "%s ha cancel·lat la transferència de %s" -#, fuzzy, c-format +#, c-format msgid "%s cancelled the file transfer" msgstr "%s ha cancel·lat la transferència del fitxer" @@ -2224,28 +2233,30 @@ "No codecs found. Install some GStreamer codecs found in GStreamer plugins " "packages." msgstr "" +"No s'ha trobat cap còdec. Instal·leu els còdecs del GStreamer que podeu " +"trobar en els paquests de connectors del GStreamer." msgid "" "No codecs left. Your codec preferences in fs-codecs.conf are too strict." msgstr "" - -#, fuzzy +"No hi ha cap més còdec. Les preferències dels còdecs al fitxer fs-codecs." +"conf són massa estrictes." + msgid "A non-recoverable Farsight2 error has occurred." -msgstr "Hi ha hagut un error de connexió desconegut: %s." - -#, fuzzy -msgid "Conference error." -msgstr "Conferència tancada" - -msgid "Error with your microphone." -msgstr "" - -msgid "Error with your webcam." -msgstr "" - -#, fuzzy, c-format +msgstr "S'ha produït un error no recuperable del Farsight2." + +msgid "Conference error" +msgstr "Error en la conferència" + +msgid "Error with your microphone" +msgstr "S'ha produït un error amb el micròfon" + +msgid "Error with your webcam" +msgstr "S'ha produït un error amb la càmera web" + +#, c-format msgid "Error creating session: %s" -msgstr "S'ha produït un error en crear la connexió" +msgstr "S'ha produït un error en crear la sessió: %s" msgid "Error creating conference." msgstr "S'ha produït un error en crear la conferència." @@ -2511,16 +2522,15 @@ msgid "Test plugin IPC support, as a server. This registers the IPC commands." msgstr "Connector de proves per a servidor d'IPC, que registra les ordres IPC." -#, fuzzy msgid "Hide Joins/Parts" -msgstr "Oculta els errors en entrar" +msgstr "Oculta en entrar/sortir" #. Translators: Followed by an input request a number of people msgid "For rooms with more than this many people" -msgstr "" +msgstr "Per sales amb més persones que" msgid "If user has not spoken in this many minutes" -msgstr "" +msgstr "Si l'usuari no ha parlat en" msgid "Apply hiding rules to buddies" msgstr "Aplica les normes d'ocultació als amics" @@ -3973,11 +3983,11 @@ msgid "Logo" msgstr "Logotip" -#, fuzzy, c-format +#, c-format msgid "" "%s will no longer be able to see your status updates. Do you want to " "continue?" -msgstr "Esteu segur que voleu suprimir %s de la llista d'amics?" +msgstr "%s no podrà veure l'actualització del vostre estat. Voleu continuar?" msgid "Cancel Presence Notification" msgstr "Cancel·la la notificació de presència" @@ -3996,6 +4006,9 @@ msgid "Unsubscribe" msgstr "Cancel·la la subscripció" +msgid "Initiate _Chat" +msgstr "Inicia un _xat" + msgid "Log In" msgstr "Connecta" @@ -4580,7 +4593,7 @@ msgid "configure: Configure a chat room." msgstr "configure: configura la sala de xat." -msgid "part [room]: Leave the room." +msgid "part [message]: Leave the room." msgstr "part [sala]: surt de la sala." msgid "register: Register with a chat room." @@ -4599,13 +4612,12 @@ "affiliate <owner|admin|member|outcast|none> [sobrenom1] " "[sobrenom2] ...: obtén els usuaris amb una afiliació, o els l'estableix." -#, fuzzy msgid "" "role <moderator|participant|visitor|none> [nick1] [nick2] ...: Get the " "users with a role or set users' role with the room." msgstr "" -"role <usuari> <moderator|participant|visitor|none> [sobrenom1] " -"[sobrenom2] ...: obtén els usuaris amb el rol especificat, o els l'estableix." +"role <moderator|participant|visitor|none> [sobrenom1] [sobrenom2] ...: " +"obtén els usuaris amb el rol especificat, o els l'estableix." msgid "invite <user> [message]: Invite a user to the room." msgstr "invite <usuari> [sala]: convida un usuari a la sala." @@ -5025,7 +5037,6 @@ msgid "Not expected" msgstr "Inesperat" -#, fuzzy msgid "Friendly name is changing too rapidly" msgstr "El nom amistós canvia massa de pressa" @@ -5245,19 +5256,16 @@ msgid "Send to Mobile" msgstr "Envia a un mòbil" -msgid "Initiate _Chat" -msgstr "Inicia un _xat" - msgid "SSL support is needed for MSN. Please install a supported SSL library." msgstr "L'MSN necessita SSL, instal·leu alguna biblioteca d'SSL permesa." #, c-format msgid "" "Unable to add the buddy %s because the username is invalid. Usernames must " -"be a valid email address." +"be valid email addresses." msgstr "" "No s'ha pogut afegir l'amic %s perquè el nom d'usuari no és vàlid. Els noms " -"d'usuari han de ser adreces de correu vàlides." +"d'usuari han de ser adreces de correu electròniques vàlides." msgid "Unable to Add" msgstr "No s'ha pogut afegir" @@ -5597,10 +5605,10 @@ "%s ha sol·licitat poder veure la vostra càmera web, però això encara no està " "implementat." -#, fuzzy, c-format +#, c-format msgid "%s invited you to view his/her webcam, but this is not yet supported." msgstr "" -"%s ha sol·licitat poder veure la vostra càmera web, però això encara no està " +"%s us ha convidat a veure la seva càmera web, però això encara no està " "implementat." msgid "Away From Computer" @@ -6354,9 +6362,9 @@ msgstr "Port en el servidor" #. Note to translators: %s in this string is a URL -#, fuzzy, c-format +#, c-format msgid "Received unexpected response from %s" -msgstr "S'ha rebut una resposta inesperada de " +msgstr "S'ha rebut una resposta inesperada de %s" #. username connecting too frequently msgid "" @@ -6369,9 +6377,9 @@ #. Note to translators: The first %s is a URL, the second is an #. error message. -#, fuzzy, c-format +#, c-format msgid "Error requesting %s: %s" -msgstr "S'ha produït en sol·licitar " +msgstr "S'ha produït un error en sol·licitar %s: %s" msgid "AOL does not allow your screen name to authenticate here" msgstr "AOL no permet que us autentiqueu amb aquest nom d'usuari aquí" @@ -7149,9 +7157,8 @@ msgid "C_onnect" msgstr "C_onnecta" -#, fuzzy msgid "You closed the connection." -msgstr "El servidor ha tancat la connexió" +msgstr "Heu tancat la connexió." msgid "Get AIM Info" msgstr "Obtén informació de AIM" @@ -7163,9 +7170,8 @@ msgid "Get Status Msg" msgstr "Aconsegueix el missatge d'estat" -#, fuzzy msgid "End Direct IM Session" -msgstr "S'ha establert una connexió directa de MI" +msgstr "Finalitzar la sessió de MI directa" msgid "Direct IM" msgstr "MI directa" @@ -8007,7 +8013,7 @@ msgid "File Send" msgstr "S'ha enviat el fitxer" -#, fuzzy, c-format +#, c-format msgid "%d cancelled the transfer of %s" msgstr "%d ha cancel·lat la transferència de %s" @@ -9545,7 +9551,7 @@ msgstr "Bloca invitacions a conferències i sales de xat" msgid "Use account proxy for SSL connections" -msgstr "" +msgstr "Empra un compte per al servidor intermediàri per a connexions SSL" msgid "Chat room list URL" msgstr "URL de la llista de sales de xat" @@ -9653,26 +9659,26 @@ msgid "Ignore buddy?" msgstr "Voleu ignorar l'amic?" -#, fuzzy msgid "Invalid username or password" -msgstr "El sobrenom o la contrasenya no són correctes" - -#, fuzzy +msgstr "El sobrenom o la contrasenya no són vàlides" + msgid "" "Your account has been locked due to too many failed login attempts. Please " "try logging into the Yahoo! website." msgstr "" -"El compte està blocat perquè s'ha intentat entrar massa cops. Això es pot " -"solucionar entrant al web de Yahoo!" +"S'ha blocat el vostre compte perquè s'ha intentat entrar massa cops. Entreu " +"al web de Yahoo! per solucionar això." #, c-format msgid "Unknown error 52. Reconnecting should fix this." -msgstr "" +msgstr "Error desconegut 52. Es pot sol·lucionar connectant de nou." msgid "" "Error 1013: The username you have entered is invalid. The most common cause " "of this error is entering your email address instead of your Yahoo! ID." msgstr "" +"Error 1013: el nom d'usuari no és vàlid. Pot ser que hagueu introduït la " +"vostra adreça de correu en lloc del nom d'usuari de Yahoo!" #, c-format msgid "Unknown error number %d. Logging into the Yahoo! website may fix this." @@ -9764,6 +9770,16 @@ msgid "Open Inbox" msgstr "Obre la safata d'entrada" +msgid "Can't send SMS. Unable to obtain mobile carrier." +msgstr "" +"No es poden enviar SMS, no s'ha pogut obtenir l'operador de telefonia mòbil." + +msgid "Can't send SMS. Unknown mobile carrier." +msgstr "No es poden enviar SMS, no es coneix l'operador de telefona mòbil." + +msgid "Getting mobile carrier to send the SMS." +msgstr "S'està obtenint l'operador de telefonia mòbil per a poder enviar SMS." + #. Write a local message to this conversation showing that a request for a #. * Doodle session has been made #. @@ -10456,7 +10472,6 @@ msgid "Layout" msgstr "Format" -#, fuzzy msgid "The layout of icons, name, and status of the buddy list" msgstr "El format de les icones, el nom, i l'estat de la llista d'amics" @@ -10513,9 +10528,8 @@ #. Note to translators: These two strings refer to the font and color #. of a buddy list buddy when it is online -#, fuzzy msgid "Online Text" -msgstr "Text en línia" +msgstr "Text en estar en línia" msgid "The text information for when a buddy is online" msgstr "Text informatiu per quan un amic estigui en línia" @@ -10523,18 +10537,16 @@ #. Note to translators: These two strings refer to the font and color #. of a buddy list buddy when it is away msgid "Away Text" -msgstr "Text d'absència" +msgstr "Text en estar absent" msgid "The text information for when a buddy is away" msgstr "Text informatiu per quan un amic estigui absent" #. Note to translators: These two strings refer to the font and color #. of a buddy list buddy when it is offline -#, fuzzy msgid "Offline Text" -msgstr "Text de fora de línia" - -#, fuzzy +msgstr "Text fora de línia" + msgid "The text information for when a buddy is offline" msgstr "Text informatiu per quan un amic estigui fora de línia" @@ -10559,7 +10571,6 @@ msgid "Message (Nick Said) Text" msgstr "Text del missatge (on s'hi ha dit el sobrenom)" -#, fuzzy msgid "" "The text information for when a chat has an unread message that mentions " "your nickname" @@ -11005,9 +11016,8 @@ msgid "_Group:" msgstr "_Grup:" -#, fuzzy msgid "Auto_join when account connects." -msgstr "_Entra automàticament quant el compte estigui connectat." +msgstr "_Entra automàticament quant es connecti el compte." msgid "_Remain in chat after window is closed." msgstr "Co_ntinua al xat quan la finestra es tanqui." @@ -11121,9 +11131,8 @@ msgid "/Conversation/New Instant _Message..." msgstr "/Conversa/_Missatge instantani nou..." -#, fuzzy msgid "/Conversation/Join a _Chat..." -msgstr "/Conversa/Con_vida..." +msgstr "/Conversa/Entra a un _xat..." msgid "/Conversation/_Find..." msgstr "/Conversa/_Cerca..." @@ -11514,7 +11523,7 @@ msgstr "Estonià" msgid "Basque" -msgstr "" +msgstr "Basc" msgid "Persian" msgstr "Persa" @@ -11728,6 +11737,13 @@ "primary language is English. You are welcome to post in another " "language, but the responses may be less helpful.

" msgstr "" +"Ajuda d'altres usuaris del Pidgin: support@pidgin.im
Aquesta és una llista de " +"correu pública. (arxiu)
No us podem ajudar amb connectors d'altres proveïdors.
En aquesta llista s'hi empra principalment l'anglès. Podeu escriure-" +"hi en un altre idioma, però és possible que les respostes no siguin de gaire " +"ajuda.

" #, c-format msgid "" @@ -12299,45 +12315,48 @@ "Usage: %s [OPTION]...\n" "\n" msgstr "" - -#, fuzzy +"Forma d'ús: %s [OPCIÓ]...\n" +"\n" + msgid "DIR" -msgstr "IRC" +msgstr "DIR" msgid "use DIR for config files" -msgstr "" +msgstr "empra DIR per a fitxers de configuració" msgid "print debugging messages to stdout" -msgstr "" +msgstr "escriu missatges de depuració a la sortida estàndard" msgid "force online, regardless of network status" -msgstr "" +msgstr "força estar en línia, independentment de l'estat de la xarxa" msgid "display this help and exit" -msgstr "" +msgstr "mostra aquesta ajuda i surt" # FIXME: entrades/registres? -#, fuzzy msgid "allow multiple instances" -msgstr "Permet diverses entrades simultànies" +msgstr "permet diverses instàncies" msgid "don't automatically login" -msgstr "" +msgstr "no entra als comptes" msgid "NAME" -msgstr "" +msgstr "NOM" msgid "" "enable specified account(s) (optional argument NAME\n" " specifies account(s) to use, separated by commas.\n" " Without this only the first account will be enabled)." msgstr "" +"habilita els comptes especificats (l'argument opcional NAME especifica\n" +" els comptes a emprar, separats per comes. Sense això\n" +" només s'habilitarà el primer compte)." msgid "X display to use" -msgstr "" +msgstr "pantalla d'X a emprar" msgid "display the current version and exit" -msgstr "" +msgstr "mostra la versió actual i surt" # FIXME: backtrace -> traça (bug-buddy) ? #, c-format @@ -12394,7 +12413,7 @@ msgstr "%s vol iniciar una sessió de vídeo." msgid "Incoming Call" -msgstr "" +msgstr "Trucada entrant" msgid "_Pause" msgstr "_Pausa" @@ -12576,50 +12595,54 @@ msgid "Pounce Target" msgstr "Objectiu de l'avís" -#, c-format msgid "Started typing" msgstr "Hagi començat a escriure" -#, c-format msgid "Paused while typing" msgstr "S'aturi mentre tecleja" -#, c-format msgid "Signed on" msgstr "Es connecti" -#, c-format msgid "Returned from being idle" msgstr "Torna a estar actiu" -#, c-format msgid "Returned from being away" msgstr "Torni a estar present" -#, c-format msgid "Stopped typing" msgstr "Pari d'escriure" -#, c-format msgid "Signed off" msgstr "Es desconnecti" -#, c-format msgid "Became idle" msgstr "Passi a inactiu" -#, c-format msgid "Went away" msgstr "En estar absent" -#, c-format msgid "Sent a message" msgstr "Envia un missatge" -#, c-format msgid "Unknown.... Please report this!" msgstr "Esdeveniment d'avís desconegut, informeu-nos-en." +msgid "(Custom)" +msgstr "(Personalitzat)" + +msgid "(Default)" +msgstr "(Predeterminat)" + +msgid "The default Pidgin sound theme" +msgstr "El tema de sons predeterminat del pidgin" + +msgid "The default Pidgin buddy list theme" +msgstr "El tema per a la llista d'amics predeterminat del Pidgin" + +msgid "The default Pidgin status icon theme" +msgstr "El tema de les icones d'estat predeterminat del Pidgin" + msgid "Theme failed to unpack." msgstr "No s'ha pogut desempaquetar el tema." @@ -12764,14 +12787,16 @@ msgid "Cannot start browser configuration program." msgstr "No s'ha pogut iniciar el programa de configuració del navegador." -#, fuzzy msgid "Disabled" -msgstr "_Inhabilita" +msgstr "Inhabilitat" #, c-format msgid "Use _automatically detected IP address: %s" msgstr "Empra l'_adreça IP detectada automàticament: %s" +msgid "ST_UN server:" +msgstr "Servidor ST_UN:" + msgid "Example: stunserver.org" msgstr "Exemple: stunserver.org" @@ -12797,9 +12822,8 @@ msgid "Relay Server (TURN)" msgstr "Servidor repetidor (TURN)" -#, fuzzy msgid "_TURN server:" -msgstr "Servidor ST_UN:" +msgstr "Servidor _TURN:" msgid "Proxy Server & Browser" msgstr "Servidor intermediari i navegador" @@ -14372,35 +14396,29 @@ "Aquest connector permet a l'usuari personalitzar els formats de les marques " "horàries de les converses i dels registres." -#, fuzzy msgid "Audio" -msgstr "Auto" - -#, fuzzy +msgstr "Àudio" + msgid "Video" msgstr " Vídeo" msgid "Output" -msgstr "" - -#, fuzzy +msgstr "Sortida" + msgid "_Plugin" -msgstr "Connectors" - -#, fuzzy +msgstr "_Connectors" + msgid "_Device" -msgstr "Dispositiu" +msgstr "_Dispositiu" msgid "Input" -msgstr "" - -#, fuzzy +msgstr "Entrada" + msgid "P_lugin" -msgstr "Connectors" - -#, fuzzy +msgstr "C_onnectors" + msgid "D_evice" -msgstr "Dispositiu" +msgstr "D_ispositiu" #. *< magic #. *< major version @@ -14411,18 +14429,19 @@ #. *< dependencies #. *< priority #. *< id -#, fuzzy msgid "Voice/Video Settings" -msgstr "Edita els paràmetres" +msgstr "Configuració del so/vídeo" #. *< name #. *< version msgid "Configure your microphone and webcam." -msgstr "" +msgstr "Configureu el micròfon i la càmera web." #. *< summary msgid "Configure microphone and webcam settings for voice/video calls." msgstr "" +"Configureu els paràmetres del micròfon i la càmera web per a trucades de veu/" +"vídeo." msgid "Opacity:" msgstr "Opacitat:" @@ -14481,9 +14500,6 @@ "\n" "* Nota: aquest connector requereix Windows 2000 o superior." -msgid "GTK+ Runtime Version" -msgstr "Versió del mòdul d'execució de GTK+" - #. Autostart msgid "Startup" msgstr "Inicialització" @@ -14492,6 +14508,10 @@ msgid "_Start %s on Windows startup" msgstr "_Inicia el %s en iniciar Windows" +# FIXME: entrades/registres? +msgid "Allow multiple instances" +msgstr "Permet diverses instàncies" + msgid "_Dockable Buddy List" msgstr "Llista _d'amics acoblable" @@ -14553,6 +14573,9 @@ msgid "This plugin is useful for debbuging XMPP servers or clients." msgstr "Aquest connector és útil per a depurar servidors i clients XMPP." +#~ msgid "GTK+ Runtime Version" +#~ msgstr "Versió del mòdul d'execució de GTK+" + #~ msgid "Calling ... " #~ msgstr "S'està trucant..." @@ -14796,9 +14819,6 @@ #~ msgid "Could not write" #~ msgstr "No s'ha pogut escriure" -#~ msgid "Could not connect" -#~ msgstr "No s'ha pogut connectar" - #~ msgid "Could not create listen socket" #~ msgstr "No s'ha pogut crear el sòcol per a escoltar"