changeset 23118:944059cb7807

Add the purple_buddy_icons_node_has_custom_icon, purple_buddy_icons_node_find_custom_icon, and purple_buddy_icons_node_set_custom_icon functions. Deprecate the purple_buddy_icons_has_custom_icon, purple_buddy_icons_find_custom_icon, and purple_buddy_icons_set_custom_icon functions. This allows custom icons to be set for PurpleChat:s and PurpleGroup:s as well as PurpleBuddy:s. The UI bits of this coming soon.
author Etan Reisner <pidgin@unreliablesource.net>
date Tue, 13 May 2008 04:36:07 +0000
parents d11c993700e6
children 21636ef92dbb
files ChangeLog.API libpurple/buddyicon.c libpurple/buddyicon.h
diffstat 3 files changed, 160 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Tue May 13 04:26:28 2008 +0000
+++ b/ChangeLog.API	Tue May 13 04:36:07 2008 +0000
@@ -6,9 +6,15 @@
 		* purple_serv_got_join_chat_failed
 		* chat-join-failed signal (see conversation-signals.dox)
 		* purple_blist_update_node_icon
+		* purple_buddy_icons_node_has_custom_icon
+		* purple_buddy_icons_node_find_custom_icon
+		* purple_buddy_icons_node_set_custom_icon
 
 		Deprecated:
 		* purple_blist_update_buddy_icon
+		* purple_buddy_icons_has_custom_icon
+		* purple_buddy_icons_find_custom_icon
+		* purple_buddy_icons_set_custom_icon
 
 	perl:
 		Added:
--- a/libpurple/buddyicon.c	Tue May 13 04:26:28 2008 +0000
+++ b/libpurple/buddyicon.c	Tue May 13 04:36:07 2008 +0000
@@ -92,8 +92,10 @@
  */
 static GHashTable *icon_file_cache = NULL;
 
-/* This one is used for both custom buddy icons
- * on PurpleContacts and account icons. */
+/**
+ * This hash table is used for both custom buddy icons on PurpleBlistNodes and
+ * account icons.
+ */
 static GHashTable *pointer_icon_cache = NULL;
 
 static char       *cache_dir     = NULL;
@@ -684,14 +686,6 @@
 	return (icon ? purple_buddy_icon_ref(icon) : NULL);
 }
 
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact)
-{
-	g_return_val_if_fail(contact != NULL, FALSE);
-
-	return (purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon") != NULL);
-}
-
 PurpleStoredImage *
 purple_buddy_icons_find_account_icon(PurpleAccount *account)
 {
@@ -807,24 +801,32 @@
 	return ret;
 }
 
-PurpleStoredImage *
-purple_buddy_icons_find_custom_icon(PurpleContact *contact)
+gboolean
+purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node)
 {
-	PurpleStoredImage *img;
-	const char *custom_icon_file;
-	const char *dirname;
+	g_return_val_if_fail(node != NULL, FALSE);
+
+	return (purple_blist_node_get_string(node, "custom_buddy_icon") != NULL);
+}
+
+PurpleStoredImage *
+purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node)
+{
 	char *path;
+	size_t len;
 	guchar *data;
-	size_t len;
+	PurpleStoredImage *img;
+	const char *custom_icon_file, *dirname;
 
-	g_return_val_if_fail(contact != NULL, NULL);
+	g_return_val_if_fail(node != NULL, NULL);
 
-	if ((img = g_hash_table_lookup(pointer_icon_cache, contact)))
+	if ((img = g_hash_table_lookup(pointer_icon_cache, node)))
 	{
 		return purple_imgstore_ref(img);
 	}
 
-	custom_icon_file = purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon");
+	custom_icon_file = purple_blist_node_get_string(node,
+	                                                "custom_buddy_icon");
 
 	if (custom_icon_file == NULL)
 		return NULL;
@@ -836,7 +838,7 @@
 	{
 		g_free(path);
 		img = purple_buddy_icon_data_new(data, len, custom_icon_file);
-		g_hash_table_insert(pointer_icon_cache, contact, img);
+		g_hash_table_insert(pointer_icon_cache, node, img);
 		return img;
 	}
 	g_free(path);
@@ -845,66 +847,79 @@
 }
 
 PurpleStoredImage *
-purple_buddy_icons_set_custom_icon(PurpleContact *contact,
-                                   guchar *icon_data, size_t icon_len)
+purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
+                                        guchar *icon_data, size_t icon_len)
 {
+	char *old_icon;
 	PurpleStoredImage *old_img;
 	PurpleStoredImage *img = NULL;
-	char *old_icon;
-	PurpleBlistNode *child;
+
+	g_return_val_if_fail(node != NULL, NULL);
 
-	old_img = g_hash_table_lookup(pointer_icon_cache, contact);
+	if (!PURPLE_BLIST_NODE_IS_CONTACT(node) &&
+	    !PURPLE_BLIST_NODE_IS_CHAT(node) &&
+	    !PURPLE_BLIST_NODE_IS_GROUP(node)) {
+		return NULL;
+	}
 
-	if (icon_data != NULL && icon_len > 0)
-	{
+	old_img = g_hash_table_lookup(pointer_icon_cache, node);
+
+	if (icon_data != NULL && icon_len > 0) {
 		img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
 	}
 
-	old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)contact,
+	old_icon = g_strdup(purple_blist_node_get_string(node,
 	                                                 "custom_buddy_icon"));
-	if (img && purple_buddy_icons_is_caching())
-	{
+	if (img && purple_buddy_icons_is_caching()) {
 		const char *filename = purple_imgstore_get_filename(img);
-		purple_blist_node_set_string((PurpleBlistNode *)contact,
-		                             "custom_buddy_icon",
+		purple_blist_node_set_string(node, "custom_buddy_icon",
 		                             filename);
 		ref_filename(filename);
-	}
-	else
-	{
-		purple_blist_node_remove_setting((PurpleBlistNode *)contact,
-		                                 "custom_buddy_icon");
+	} else {
+		purple_blist_node_remove_setting(node, "custom_buddy_icon");
 	}
 	unref_filename(old_icon);
 
 	if (img)
-		g_hash_table_insert(pointer_icon_cache, contact, img);
+		g_hash_table_insert(pointer_icon_cache, node, img);
 	else
-		g_hash_table_remove(pointer_icon_cache, contact);
+		g_hash_table_remove(pointer_icon_cache, node);
 
-	for (child = contact->node.child ; child ; child = child->next)
-	{
-		PurpleBuddy *buddy;
-		PurpleConversation *conv;
+	if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
+		PurpleBlistNode *child;
+		for (child = node->child ; child ; child = child->next)
+		{
+			PurpleBuddy *buddy;
+			PurpleConversation *conv;
+
+			if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
+				continue;
+
+			buddy = (PurpleBuddy *)child;
 
-		if (!PURPLE_BLIST_NODE_IS_BUDDY(child))
-			continue;
-
-		buddy = (PurpleBuddy *)child;
+			conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy));
+			if (conv)
+				purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);
 
-		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
-		                                             purple_buddy_get_name(buddy),
-		                                             purple_buddy_get_account(buddy));
-		if (conv)
+			/* Is this call necessary anymore? Can the buddies
+			 * themselves need updating when the custom buddy
+			 * icon changes? */
+			purple_blist_update_node_icon((PurpleBlistNode*)buddy);
+		}
+	} else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
+		PurpleConversation *conv = NULL;
+
+		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node));
+		if (conv) {
 			purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON);
-
-		purple_blist_update_buddy_icon(buddy);
+		}
 	}
 
-	if (old_img)
+	purple_blist_update_node_icon(node);
+
+	if (old_img) {
 		purple_imgstore_unref(old_img);
-	else if (old_icon)
-	{
+	} else if (old_icon) {
 		/* The old icon may not have been loaded into memory.  In that
 		 * case, we'll need to uncache the filename.  The filenames
 		 * are ref-counted, so this is safe. */
@@ -915,6 +930,27 @@
 	return img;
 }
 
+#ifndef PURPLE_DISABLE_DEPRECATED
+gboolean
+purple_buddy_icons_has_custom_icon(PurpleContact *contact)
+{
+	return purple_buddy_icons_node_has_custom_icon((PurpleBlistNode*)contact);
+}
+
+PurpleStoredImage *
+purple_buddy_icons_find_custom_icon(PurpleContact *contact)
+{
+	return purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
+}
+
+PurpleStoredImage *
+purple_buddy_icons_set_custom_icon(PurpleContact *contact, guchar *icon_data,
+                                   size_t icon_len)
+{
+	return purple_buddy_icons_node_set_custom_icon((PurpleBlistNode*)contact, icon_data, icon_len);
+}
+#endif
+
 void
 _purple_buddy_icon_set_old_icons_dir(const char *dirname)
 {
@@ -1138,7 +1174,9 @@
 				}
 			}
 		}
-		else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
+		else if (PURPLE_BLIST_NODE_IS_CONTACT(node) ||
+		         PURPLE_BLIST_NODE_IS_CHAT(node) ||
+		         PURPLE_BLIST_NODE_IS_GROUP(node))
 		{
 			const char *filename;
 
--- a/libpurple/buddyicon.h	Tue May 13 04:26:28 2008 +0000
+++ b/libpurple/buddyicon.h	Tue May 13 04:36:07 2008 +0000
@@ -218,16 +218,6 @@
 purple_buddy_icons_find(PurpleAccount *account, const char *username);
 
 /**
- * Returns a boolean indicating if a given contact has a custom buddy icon.
- *
- * @param contact The contact
- *
- * @return A boolean indicating if @a contact has a custom buddy icon.
- */
-gboolean
-purple_buddy_icons_has_custom_icon(PurpleContact *contact);
-
-/**
  * Returns the buddy icon image for an account.
  *
  * The caller owns a reference to the image in the store, and must dereference
@@ -277,7 +267,18 @@
 purple_buddy_icons_get_account_icon_timestamp(PurpleAccount *account);
 
 /**
- * Returns the custom buddy icon image for a contact.
+ * Returns a boolean indicating if a given blist node has a custom buddy icon.
+ *
+ * @param node The blist node.
+ *
+ * @return A boolean indicating if @a node has a custom buddy icon.
+ * @since 2.5.0
+ */
+gboolean
+purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node);
+
+/**
+ * Returns the custom buddy icon image for a blist node.
  *
  * The caller owns a reference to the image in the store, and must dereference
  * the image with purple_imgstore_unref() for it to be freed.
@@ -286,31 +287,65 @@
  * needed, so it should be called in any case where you want the
  * appropriate icon.
  *
- * @param contact The contact
+ * @param node The node.
+ *
+ * @return The custom buddy icon.
+ * @since 2.5.0
+ */
+PurpleStoredImage *
+purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node);
+
+/**
+ * Sets a custom buddy icon for a blist node.
+ *
+ * This function will deal with saving a record of the icon, caching the data,
+ * etc.
+ *
+ * @param node      The blist node for which to set a custom icon.
+ * @param icon_data The image data of the icon, which the buddy icon code will
+ *                  free.
+ * @param icon_len  The length of the data in @a icon_data.
  *
- * @return The custom buddy icon image.
+ * @return The icon that was set. The caller does NOT own a reference to this,
+ *         and must call purple_imgstore_ref() if it wants one.
+ * @since 2.5.0
+ */
+PurpleStoredImage *
+purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node,
+                                        guchar *icon_data, size_t icon_len);
+
+#ifndef PURPLE_DISABLE_DEPRECATED
+/**
+ * PurpleContact version of purple_buddy_icons_node_has_custom_icon.
+ *
+ * @copydoc purple_buddy_icons_node_has_custom_icon()
+ *
+ * @deprecated Use purple_buddy_icons_node_has_custom_icon instead.
+ */
+gboolean
+purple_buddy_icons_has_custom_icon(PurpleContact *contact);
+
+/**
+ * PurpleContact version of purple_buddy_icons_node_find_custom_icon.
+ *
+ * @copydoc purple_buddy_icons_node_find_custom_icon()
+ *
+ * @deprecated Use purple_buddy_icons_node_find_custom_icon instead.
  */
 PurpleStoredImage *
 purple_buddy_icons_find_custom_icon(PurpleContact *contact);
 
 /**
- * Sets a custom buddy icon for a user.
- *
- * This function will deal with saving a record of the icon,
- * caching the data, etc.
+ * PurpleContact version of purple_buddy_icons_node_set_custom_icon.
  *
- * @param contact   The contact for which to set a custom icon.
- * @param icon_data The image data of the icon, which the
- *                  buddy icon code will free.
- * @param icon_len  The length of the data in @a icon_data.
+ * @copydoc purple_buddy_icons_node_set_custom_icon()
  *
- * @return The icon that was set.  The caller does NOT own
- *         a reference to this, and must call purple_imgstore_ref()
- *         if it wants one.
+ * @deprecated Use purple_buddy_icons_node_set_custom_icon instead.
  */
 PurpleStoredImage *
 purple_buddy_icons_set_custom_icon(PurpleContact *contact,
                                    guchar *icon_data, size_t icon_len);
+#endif
 
 /**
  * Sets whether or not buddy icon caching is enabled.