changeset 18266:8119af5b3649

merge of '399a02c013c99bd424dd48e241b264b786754576' and '9beed54f9b14fec268ec3cecae10261a9d43e1c8'
author Mark Doliner <mark@kingant.net>
date Sun, 24 Jun 2007 17:07:34 +0000
parents 83ea1733979b (current diff) a2c488006756 (diff)
children 0d7ce1dca9fa
files
diffstat 12 files changed, 92 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/jabber/.todo	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/protocols/jabber/.todo	Sun Jun 24 17:07:34 2007 +0000
@@ -1,13 +1,4 @@
 <todo version="0.1.19">
-    <note priority="verylow" time="1036043981" done="1089237837">
-        *sigh* file transfer (do we really need/want this?)
-        <comment>
-            faceprint did this
-        </comment>
-    </note>
-    <note priority="high" time="1036043427">
-        problem seeing buddies with long blist?
-    </note>
     <note priority="medium" time="1036044198">
         Browsing
     </note>
@@ -17,12 +8,6 @@
     <note priority="medium" time="1036044448">
         Add option for user info to be published or not in JUD.
     </note>
-    <note priority="medium" time="1036044571">
-        Show self on buddylist
-        <comment>
-            is this done?
-        </comment>
-    </note>
     <note priority="medium" time="1036044583">
         Delete server account.
     </note>
@@ -37,9 +22,6 @@
         <note priority="medium" time="1037893000">
             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)
         </note>
-        <note priority="low" time="1037890968">
-            have set info pre-fill values from the server when no local vcard exists. this will help people migrating to libpurple-based clients
-        </note>
     </note>
     <note priority="verylow" time="1036044192">
         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.)
--- a/libpurple/protocols/jabber/buddy.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Sun Jun 24 17:07:34 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);
--- a/libpurple/protocols/jabber/disco.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/protocols/jabber/disco.c	Sun Jun 24 17:07:34 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")
--- a/libpurple/protocols/jabber/iq.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/protocols/jabber/iq.c	Sun Jun 24 17:07:34 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);
--- a/libpurple/protocols/oscar/peer.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/protocols/oscar/peer.c	Sun Jun 24 17:07:34 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)
--- a/libpurple/util.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/util.c	Sun Jun 24 17:07:34 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;
--- a/libpurple/util.h	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/util.h	Sun Jun 24 17:07:34 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
--- a/libpurple/xmlnode.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/libpurple/xmlnode.c	Sun Jun 24 17:07:34 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);
--- a/pidgin/gtkconv.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/pidgin/gtkconv.c	Sun Jun 24 17:07:34 2007 +0000
@@ -8560,7 +8560,7 @@
 	win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
 
 	if (!win->gtkconvs || !win->gtkconvs->next)
-		gtk_notebook_set_show_tabs(win->notebook, FALSE);
+		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
 
 	if (!win->gtkconvs && win != hidden_convwin)
 		pidgin_conv_window_destroy(win);
--- a/pidgin/pidginstock.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/pidgin/pidginstock.c	Sun Jun 24 17:07:34 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 *
--- a/pidgin/pidginstock.h	Sat Jun 23 18:53:14 2007 +0000
+++ b/pidgin/pidginstock.h	Sun Jun 24 17:07:34 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"
 
 
 /*@}*/
--- a/pidgin/plugins/gtkbuddynote.c	Sat Jun 23 18:53:14 2007 +0000
+++ b/pidgin/plugins/gtkbuddynote.c	Sun Jun 24 17:07:34 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, _("\n<b>Buddy Note</b>: %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;
 	}