changeset 29094:15b1cc2e8b74

propagate from branch 'im.pidgin.pidgin' (head 181764ee5b9643826233ae4d6eefb5be194cca08) to branch 'im.pidgin.pidgin.next.minor' (head e7173f7cc4a5f995e71e0a3425c6f88ca547b156)
author John Bailey <rekkanoryo@rekkanoryo.org>
date Mon, 24 Aug 2009 14:48:06 +0000
parents 9affcab62522 (diff) bc93b46e65e7 (current diff)
children b641af9dfe2a
files ChangeLog libpurple/protocols/yahoo/libymsg.c pidgin/gtkcelllayout.c pidgin/gtkcelllayout.h pidgin/gtkcellrendererprogress.c pidgin/gtkcellrendererprogress.h pidgin/gtkcellview.c pidgin/gtkcellview.h pidgin/gtkcellviewmenuitem.c pidgin/gtkcellviewmenuitem.h pidgin/gtkexpander.c pidgin/gtkexpander.h pidgin/gtknotify.c pidgin/pidgincombobox.c pidgin/pidgincombobox.h
diffstat 11 files changed, 161 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Aug 23 22:11:44 2009 +0000
+++ b/ChangeLog	Mon Aug 24 14:48:06 2009 +0000
@@ -6,6 +6,7 @@
 	libpurple:
 	* Fix --disable-avahi to actually disable it in configure, as opposed
 	  to just making the warning non-fatal.
+	* Sending custom smileys in MSN chats is now supported.
 
 	XMPP:
 	* Prompt the user before cancelling a presence subscription.
--- a/libpurple/dbus-analyze-functions.py	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/dbus-analyze-functions.py	Mon Aug 24 14:48:06 2009 +0000
@@ -181,15 +181,20 @@
 
    
     def processoutput(self, type, name):
+        const = False
+        unsigned = False
         # the "void" type is simple ...
         if type == ["void"]:
             return self.outputvoid(type, name)
 
-        const = False
         if type[0] == "const":
             type = type[1:]
             const = True
 
+        if type[0] == "unsigned":
+            type = type[1:]
+            unsigned = True
+
         # a string
         if type == ["char", pointer] or type == ["gchar", pointer]:
             return self.outputstring(type, name, const)
@@ -197,7 +202,7 @@
         # simple types (ints, booleans, enums, ...)
         if (len(type) == 1) and \
                ((type[0] in simpletypes) or (type[0].startswith("Purple"))):
-            return self.outputsimple(type, name)
+            return self.outputsimple(type, name, unsigned)
 
         # pointers ...
         if (len(type) == 2) and (type[1] == pointer):
@@ -303,10 +308,13 @@
 #        self.returncode.append("NULLIFY(%s);" % name)
         self.returncode.append("return %s;" % name);
 
-    def outputsimple(self, type, name):
+    def outputsimple(self, type, name, us):
         self.functiontype = type[0]
         self.decls.append("%s %s = 0;" % (type[0], name))
-        self.outputparams.append(("G_TYPE_INT", name))
+        if us:
+            self.outputparams.append(("G_TYPE_UINT", name))
+        else:
+            self.outputparams.append(("G_TYPE_INT", name))
         self.returncode.append("return %s;" % name);
 
     # we could add "const" to the return type but this would probably
@@ -455,11 +463,16 @@
         if not const:
             self.ccodeout.append("\tg_free(%s);" % name)
 
-    def outputsimple(self, type, name):
-        self.cdecls.append("\tdbus_int32_t %s;" % name)
+    def outputsimple(self, type, name, us):
+        if us:
+            self.cdecls.append("\tdbus_uint32_t %s;" % name)
+            self.cparamsout.append(("UINT32", name))
+            self.addouttype("u", name)
+        else:
+            self.cdecls.append("\tdbus_int32_t %s;" % name)
+            self.cparamsout.append(("INT32", name))
+            self.addouttype("i", name)
         self.ccode.append("\t%s = %s;" % (name, self.call))
-        self.cparamsout.append(("INT32", name))
-        self.addouttype("i", name)
 
     def outputpurplestructure(self, type, name):
         self.cdecls.append("\tdbus_int32_t %s;" % name)
--- a/libpurple/media.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/media.c	Mon Aug 24 14:48:06 2009 +0000
@@ -2129,6 +2129,35 @@
 			}
 			break;
 		}
+		case GST_MESSAGE_ERROR: {
+			GstElement *element = GST_ELEMENT(GST_MESSAGE_SRC(msg));
+			GstElement *lastElement = NULL;
+			while (!GST_IS_PIPELINE(element)) {
+				if (element == media->priv->confbin) {
+					purple_media_error("media", _("Conference error."));
+					purple_media_end(media, NULL, NULL);
+					break;
+				}
+				lastElement = element;
+				element = GST_ELEMENT_PARENT(element);
+			}
+			if (GST_IS_PIPELINE(element)) {
+				GList *sessions = g_hash_table_get_values(media->priv->sessions);
+				for (; sessions; sessions = g_list_delete_link(sessions, sessions)) {
+					PurpleMediaSession *session = sessions->data;
+
+					if (session->src == lastElement) {
+						if (session->type & PURPLE_MEDIA_AUDIO)
+							purple_media_error(media, _("Error with your microphone."));
+						else
+							purple_media_error(media, _("Error with your webcam."));
+						purple_media_end(media, NULL, NULL);
+						break;
+					}
+				}
+				g_list_free(sessions);
+			}
+		}
 		default:
 			break;
 	}
--- a/libpurple/protocols/msn/msn.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/protocols/msn/msn.c	Mon Aug 24 14:48:06 2009 +0000
@@ -89,6 +89,7 @@
 typedef struct
 {
 	char *smile;
+	PurpleSmiley *ps;
 	MsnObject *obj;
 } MsnEmoticon;
 
@@ -1082,12 +1083,10 @@
 	strobj = msn_object_to_string(obj);
 
 	if (current)
-		g_string_append_printf(current, "\t%s\t%s",
-				emoticon->smile, strobj);
+		g_string_append_printf(current, "\t%s\t%s", emoticon->smile, strobj);
 	else {
 		current = g_string_new("");
-		g_string_printf(current,"%s\t%s",
-					emoticon->smile, strobj);
+		g_string_printf(current, "%s\t%s", emoticon->smile, strobj);
 	}
 
 	g_free(strobj);
@@ -1145,6 +1144,7 @@
 
 		emoticon = g_new0(MsnEmoticon, 1);
 		emoticon->smile = g_strdup(purple_smiley_get_shortcut(smiley));
+		emoticon->ps = smiley;
 		emoticon->obj = msn_object_new_from_image(img,
 				purple_imgstore_get_filename(img),
 				username, MSN_OBJECT_EMOTICON);
@@ -1167,7 +1167,7 @@
 
 	smileys = msn_msg_grab_emoticons(msg->body, username);
 	while (smileys) {
-		smile = (MsnEmoticon*)smileys->data;
+		smile = (MsnEmoticon *)smileys->data;
 		emoticons = msn_msg_emoticon_add(emoticons, smile);
 		msn_emoticon_destroy(smile);
 		smileys = g_slist_delete_link(smileys, smileys);
@@ -1718,13 +1718,19 @@
 {
 	PurpleAccount *account;
 	MsnSession *session;
+	const char *username;
 	MsnSwitchBoard *swboard;
 	MsnMessage *msg;
 	char *msgformat;
 	char *msgtext;
+	size_t msglen;
+	MsnEmoticon *smile;
+	GSList *smileys;
+	GString *emoticons = NULL;
 
 	account = purple_connection_get_account(gc);
 	session = gc->proto_data;
+	username = purple_account_get_username(account);
 	swboard = msn_session_find_swboard_with_id(session, id);
 
 	if (swboard == NULL)
@@ -1736,8 +1742,9 @@
 	swboard->flag |= MSN_SB_FLAG_IM;
 
 	msn_import_html(message, &msgformat, &msgtext);
-
-	if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564)
+	msglen = strlen(msgtext);
+
+	if ((msglen == 0) || (msglen + strlen(msgformat) + strlen(VERSION) > 1564))
 	{
 		g_free(msgformat);
 		g_free(msgtext);
@@ -1747,6 +1754,29 @@
 
 	msg = msn_message_new_plain(msgtext);
 	msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
+
+	smileys = msn_msg_grab_emoticons(msg->body, username);
+	while (smileys) {
+		smile = (MsnEmoticon *)smileys->data;
+		emoticons = msn_msg_emoticon_add(emoticons, smile);
+		if (purple_conv_custom_smiley_add(swboard->conv, smile->smile,
+		                                  "sha1", purple_smiley_get_checksum(smile->ps),
+		                                  FALSE)) {
+			gconstpointer data;
+			size_t len;
+			data = purple_smiley_get_data(smile->ps, &len);
+			purple_conv_custom_smiley_write(swboard->conv, smile->smile, data, len);
+			purple_conv_custom_smiley_close(swboard->conv, smile->smile);
+		}
+		msn_emoticon_destroy(smile);
+		smileys = g_slist_delete_link(smileys, smileys);
+	}
+
+	if (emoticons) {
+		msn_send_emoticons(swboard, emoticons);
+		g_string_free(emoticons, TRUE);
+	}
+
 	msn_switchboard_send_msg(swboard, msg, FALSE);
 	msn_message_destroy(msg);
 
--- a/libpurple/protocols/msn/slpcall.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Mon Aug 24 14:48:06 2009 +0000
@@ -205,7 +205,7 @@
 		if (slpmsg->session_id == 64)
 		{
 			/* This is for handwritten messages (Ink) */
-			GError *error;
+			GError *error = NULL;
 			gsize bytes_read, bytes_written;
 
 			body_str = g_convert((const gchar *)body, body_len / 2,
@@ -232,7 +232,7 @@
 			g_free(body_str);
 
 			body_str = g_convert((const gchar *)body, body_len / 2,
-			                     "UTF-8", "UTF16-LE",
+			                     "UTF-8", "UTF-16LE",
 			                     &bytes_read, &bytes_written, &error);
 			if (!body_str)
 			{
--- a/libpurple/protocols/yahoo/libymsg.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/protocols/yahoo/libymsg.c	Mon Aug 24 14:48:06 2009 +0000
@@ -4494,8 +4494,6 @@
 
 	if (purple_presence_is_idle(presence))
 		yahoo_packet_hash_str(pkt, 47, "2");
-	else if (!purple_status_is_available(status))
-		yahoo_packet_hash_str(pkt, 47, "1");
 
 	yahoo_packet_send_and_free(pkt, yd);
 
@@ -4516,6 +4514,7 @@
 	struct yahoo_packet *pkt = NULL;
 	char *msg = NULL, *msg2 = NULL;
 	PurpleStatus *status = NULL;
+	gboolean invisible = FALSE;
 
 	if (idle && yd->current_status != YAHOO_STATUS_CUSTOM)
 		yd->current_status = YAHOO_STATUS_IDLE;
@@ -4524,9 +4523,15 @@
 		yd->current_status = get_yahoo_status_from_purple_status(status);
 	}
 
+	invisible = !( purple_presence_is_available(purple_account_get_presence(purple_connection_get_account(gc))) );
+
 	pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, YAHOO_STATUS_AVAILABLE, yd->session_id);
 
-	yahoo_packet_hash_int(pkt, 10, yd->current_status);
+	if (!idle && invisible)
+		yahoo_packet_hash_int(pkt, 10, YAHOO_STATUS_AVAILABLE);
+	else
+		yahoo_packet_hash_int(pkt, 10, yd->current_status);
+
 	if (yd->current_status == YAHOO_STATUS_CUSTOM) {
 		const char *tmp;
 		if (status == NULL)
@@ -4549,8 +4554,6 @@
 
 	if (idle)
 		yahoo_packet_hash_str(pkt, 47, "2");
-	else if (!purple_presence_is_available(purple_account_get_presence(purple_connection_get_account(gc))))
-		yahoo_packet_hash_str(pkt, 47, "1");
 
 	yahoo_packet_send_and_free(pkt, yd);
 
--- a/libpurple/smiley.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/smiley.c	Mon Aug 24 14:48:06 2009 +0000
@@ -80,7 +80,7 @@
  * XML descriptor file layout                                                 *
  ******************************************************************************
  *
- * Althought we are creating the profile XML structure here, now we
+ * Although we are creating the profile XML structure here, now we
  * won't handle it.
  * So, we just add one profile named "default" that has no associated
  * account elements, and have only the smiley_set that will contain
@@ -163,14 +163,14 @@
 }
 
 static xmlnode *
-smileys_to_xmlnode()
+smileys_to_xmlnode(void)
 {
 	xmlnode *root_node, *profile_node, *smileyset_node;
 
 	root_node = xmlnode_new(XML_ROOT_TAG);
 	xmlnode_set_attrib(root_node, "version", "1.0");
 
-	/* See the top comment's above to understand why initial tag elements
+	/* See the top comments above to understand why initial tag elements
 	 * are not being considered by now. */
 	profile_node = xmlnode_new(XML_PROFILE_TAG);
 	if (profile_node) {
@@ -188,7 +188,7 @@
 }
 
 static void
-sync_smileys()
+sync_smileys(void)
 {
 	xmlnode *root_node;
 	char *data;
@@ -216,7 +216,7 @@
 }
 
 static void
-purple_smileys_save()
+purple_smileys_save(void)
 {
 	if (save_timer == 0)
 		save_timer = purple_timeout_add_seconds(5, save_smileys_cb, NULL);
@@ -248,7 +248,7 @@
 }
 
 static void
-purple_smileys_load()
+purple_smileys_load(void)
 {
 	xmlnode *root_node, *profile_node;
 	xmlnode *smileyset_node = NULL;
@@ -262,7 +262,7 @@
 	if (root_node == NULL)
 		return;
 
-	/* See the top comment's above to understand why initial tag elements
+	/* See the top comments above to understand why initial tag elements
 	 * are not being considered by now. */
 	profile_node = xmlnode_get_child(root_node, XML_PROFILE_TAG);
 	if (profile_node)
@@ -456,7 +456,7 @@
 }
 
 /*********************************************************************
- * Other Stuff                                                             *
+ * Other Stuff                                                       *
  *********************************************************************/
 
 static char *get_file_full_path(const char *filename)
@@ -876,7 +876,7 @@
 }
 
 void
-purple_smileys_init()
+purple_smileys_init(void)
 {
 	smiley_shortcut_index = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 	smiley_checksum_index = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
@@ -887,7 +887,7 @@
 }
 
 void
-purple_smileys_uninit()
+purple_smileys_uninit(void)
 {
 	if (save_timer != 0) {
 		purple_timeout_remove(save_timer);
--- a/libpurple/smiley.h	Sun Aug 23 22:11:44 2009 +0000
+++ b/libpurple/smiley.h	Mon Aug 24 14:48:06 2009 +0000
@@ -95,7 +95,7 @@
 purple_smiley_new_from_file(const char *shortcut, const char *filepath);
 
 /**
- * Destroys the custom smiley and release the associated resources.
+ * Destroys the custom smiley and releases the associated resources.
  *
  * @param smiley    The custom smiley.
  */
@@ -183,7 +183,7 @@
  * If the custom smiley has data and the file exists in the cache, this
  * will return a full path to the cached file.
  *
- * In general, it is not appropriate to be poking in the file cached
+ * In general, it is not appropriate to be poking in the file cache
  * directly.  If you find yourself wanting to use this function, think
  * very long and hard about it, and then don't.
  *
--- a/pidgin/gtkdialogs.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/pidgin/gtkdialogs.c	Mon Aug 24 14:48:06 2009 +0000
@@ -478,7 +478,7 @@
 				" <A HREF=\"http://pidgin.im/pipermail/support/\">publicly"
 				" archived!</A>  Furthermore, we do <I><B>not</B></I> support"
 				" MXit, Facebook, Skype, or any other third-party plugins on"
-				" this list.<BR/><BR/>"));
+				" this list.)<BR/><BR/>"));
 	g_string_append_printf(str, _("<FONT SIZE=\"4\">IRC Channel:</FONT> "
 				"#pidgin on irc.freenode.net<BR><BR>"));
 	g_string_append_printf(str, _("<FONT SIZE=\"4\">XMPP MUC:</FONT> "
--- a/pidgin/gtknotify.c	Sun Aug 23 22:11:44 2009 +0000
+++ b/pidgin/gtknotify.c	Mon Aug 24 14:48:06 2009 +0000
@@ -211,25 +211,53 @@
 static void
 pounce_response_dismiss()
 {
+	GtkTreeModel *model = GTK_TREE_MODEL(pounce_dialog->treemodel);
 	GtkTreeSelection *selection;
 	GtkTreeIter iter;
+	GtkTreeIter new_selection;
 	GList *list = NULL;
+	gboolean found_selection = FALSE;
 
 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pounce_dialog->treeview));
 	gtk_tree_selection_selected_foreach(selection, delete_foreach, pounce_dialog);
 	gtk_tree_selection_selected_foreach(selection, append_to_list, &list);
 
+	g_return_if_fail(list != NULL);
+
+	if (list->next == NULL) {
+		gtk_tree_model_get_iter(model, &new_selection, list->data);
+		if (gtk_tree_model_iter_next(model, &new_selection))
+			found_selection = TRUE;
+		else {
+			/* This is the last thing in the list */
+			GtkTreePath *path;
+
+			/* Because gtk_tree_model_iter_prev doesn't exist... */
+			gtk_tree_model_get_iter(model, &new_selection, list->data);
+			path = gtk_tree_model_get_path(model, &new_selection);
+			if (gtk_tree_path_prev(path)) {
+				gtk_tree_model_get_iter(model, &new_selection, path);
+				found_selection = TRUE;
+			}
+
+			gtk_tree_path_free(path);
+		}
+	}
+
 	while (list) {
-		GtkTreeIter iter;
-		if (gtk_tree_model_get_iter(GTK_TREE_MODEL(pounce_dialog->treemodel), &iter,
-					list->data)) {
+		if (gtk_tree_model_get_iter(model, &iter, list->data)) {
 			gtk_tree_store_remove(GTK_TREE_STORE(pounce_dialog->treemodel), &iter);
 		}
 		gtk_tree_path_free(list->data);
 		list = g_list_delete_link(list, list);
 	}
 
-	if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(pounce_dialog->treemodel), &iter))
+	if (gtk_tree_model_get_iter_first(model, &iter)) {
+		if (found_selection)
+			gtk_tree_selection_select_iter(selection, &new_selection);
+		else
+			gtk_tree_selection_select_iter(selection, &iter);
+	} else
 		pounce_response_close(pounce_dialog);
 }
 
@@ -240,7 +268,7 @@
 
 	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pounce_dialog->treeview));
 	gtk_tree_selection_selected_foreach(selection, open_im_foreach, pounce_dialog);
-	
+
 	pounce_response_dismiss();
 }
 
@@ -1395,6 +1423,7 @@
 	GdkPixbuf *icon;
 	GtkTreeIter iter;
 	PidginNotifyPounceData *pounce_data;
+	gboolean first = (pounce_dialog == NULL);
 
 	if (pounce_dialog == NULL)
 		pounce_dialog = pidgin_create_notification_dialog(PIDGIN_NOTIFY_POUNCE);
@@ -1418,6 +1447,12 @@
 			PIDGIN_POUNCE_DATA, pounce_data,
 			-1);
 
+	if (first) {
+		GtkTreeSelection *selection =
+				gtk_tree_view_get_selection(GTK_TREE_VIEW(pounce_dialog->treeview));
+		gtk_tree_selection_select_iter(selection, &iter);
+	}
+
 	if (icon)
 		g_object_unref(icon);
 
@@ -1456,9 +1491,7 @@
 				G_TYPE_STRING, G_TYPE_POINTER);
 	}
 
-	dialog = gtk_dialog_new_with_buttons(NULL, NULL, 0,
-			GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-			NULL);
+	dialog = gtk_dialog_new();
 
 	/* Setup the dialog */
 	gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE);
@@ -1532,17 +1565,17 @@
 						_("IM"), GTK_RESPONSE_YES);
 		gtk_widget_set_sensitive(button, FALSE);
 		spec_dialog->open_button = button;
-	
+
+		button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+						PIDGIN_STOCK_MODIFY, GTK_RESPONSE_APPLY);
+		gtk_widget_set_sensitive(button, FALSE);
+		spec_dialog->edit_button = button;
+
 		button = gtk_dialog_add_button(GTK_DIALOG(dialog),
 						_("Dismiss"), GTK_RESPONSE_NO);
 		gtk_widget_set_sensitive(button, FALSE);
 		spec_dialog->dismiss_button = button;
 
-		button = gtk_dialog_add_button(GTK_DIALOG(dialog),
-						PIDGIN_STOCK_EDIT, GTK_RESPONSE_APPLY);
-		gtk_widget_set_sensitive(button, FALSE);
-		spec_dialog->edit_button = button;
-
 		g_signal_connect(G_OBJECT(dialog), "response",
 						 G_CALLBACK(pounce_response_cb), spec_dialog);
 
@@ -1593,6 +1626,9 @@
 			G_CALLBACK(pounce_response_open_ims), NULL);
 	}
 
+	button = gtk_dialog_add_button(GTK_DIALOG(dialog),
+	                               GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
 	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
Binary file pidgin/pixmaps/status/11/invisible.png has changed