changeset 13373:1ca4a579eb57

[gaim-migrate @ 15746] Parts of sf patch #1438833, from Sadrul Habib Chowdhury "This patch enables removing message-text from a status. Currently when you have some status with a message, and you remove the message from the statusbox-entry, the new status with no message is not used (reported in a number of bugs, like #1431289, #1431801)." committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 02 Mar 2006 04:51:09 +0000
parents fb178093e364
children 14d1892e0932
files src/prpl.c src/prpl.h src/status.c
diffstat 3 files changed, 60 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/src/prpl.c	Thu Mar 02 02:12:43 2006 +0000
+++ b/src/prpl.c	Thu Mar 02 04:51:09 2006 +0000
@@ -58,103 +58,12 @@
 	gaim_presence_set_login_time(presence, login_time);
 }
 
-static gboolean
-set_value_from_arg(GaimStatus *status, const char *id, va_list *args)
-{
-	GaimValue *value;
-
-	value = gaim_status_get_attr_value(status, id);
-
-	if (value == NULL)
-	{
-		gaim_debug_error("prpl",
-						 "Attempted to set an unknown attribute %s on "
-						 "status %s\n",
-						 id, gaim_status_get_id(status));
-		return FALSE;
-	}
-
-	switch (gaim_value_get_type(value))
-	{
-		case GAIM_TYPE_CHAR:
-			gaim_value_set_char(value, (char)va_arg(*args, int));
-			break;
-
-		case GAIM_TYPE_UCHAR:
-			gaim_value_set_uchar(value,
-								 (unsigned char)va_arg(*args, unsigned int));
-			break;
-
-		case GAIM_TYPE_BOOLEAN:
-			gaim_value_set_boolean(value, va_arg(*args, gboolean));
-			break;
-
-		case GAIM_TYPE_SHORT:
-			gaim_value_set_short(value, (short)va_arg(*args, int));
-			break;
-
-		case GAIM_TYPE_USHORT:
-			gaim_value_set_ushort(value,
-					(unsigned short)va_arg(*args, unsigned int));
-			break;
-
-		case GAIM_TYPE_INT:
-			gaim_value_set_int(value, va_arg(*args, int));
-			break;
-
-		case GAIM_TYPE_UINT:
-			gaim_value_set_uint(value, va_arg(*args, unsigned int));
-			break;
-
-		case GAIM_TYPE_LONG:
-			gaim_value_set_long(value, va_arg(*args, long));
-			break;
-
-		case GAIM_TYPE_ULONG:
-			gaim_value_set_ulong(value, va_arg(*args, unsigned long));
-			break;
-
-		case GAIM_TYPE_INT64:
-			gaim_value_set_int64(value, va_arg(*args, gint64));
-			break;
-
-		case GAIM_TYPE_UINT64:
-			gaim_value_set_uint64(value, va_arg(*args, guint64));
-			break;
-
-		case GAIM_TYPE_STRING:
-			gaim_value_set_string(value, va_arg(*args, char *));
-			break;
-
-		case GAIM_TYPE_OBJECT:
-			gaim_value_set_object(value, va_arg(*args, void *));
-			break;
-
-		case GAIM_TYPE_POINTER:
-			gaim_value_set_pointer(value, va_arg(*args, void *));
-			break;
-
-		case GAIM_TYPE_ENUM:
-			gaim_value_set_enum(value, va_arg(*args, int));
-			break;
-
-		case GAIM_TYPE_BOXED:
-			gaim_value_set_boxed(value, va_arg(*args, void *));
-			break;
-
-		default:
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
 void
-gaim_prpl_got_account_status(GaimAccount *account, const char *status_id,
-		const char *attr_id, ...)
+gaim_prpl_got_account_status(GaimAccount *account, const char *status_id, ...)
 {
 	GaimPresence *presence;
 	GaimStatus *status;
+	va_list args;
 
 	g_return_if_fail(account   != NULL);
 	g_return_if_fail(status_id != NULL);
@@ -165,23 +74,9 @@
 
 	g_return_if_fail(status != NULL);
 
-	if (attr_id != NULL)
-	{
-		va_list args;
-
-		va_start(args, attr_id);
-
-		while (attr_id != NULL)
-		{
-			set_value_from_arg(status, attr_id, &args);
-
-			attr_id = va_arg(args, char *);
-		}
-
-		va_end(args);
-	}
-
-	gaim_presence_set_status_active(presence, status_id, TRUE);
+	va_start(args, status_id);
+	gaim_status_set_active_with_attrs(status, TRUE, args);
+	va_end(args);
 }
 
 void
@@ -226,13 +121,14 @@
 
 void
 gaim_prpl_got_user_status(GaimAccount *account, const char *name,
-		const char *status_id, const char *attr_id, ...)
+		const char *status_id, ...)
 {
 	GSList *list, *iter;
 	GaimBuddy *buddy;
 	GaimPresence *presence;
 	GaimStatus *status;
 	GaimStatus *old_status;
+	va_list args;
 
 	g_return_if_fail(account   != NULL);
 	g_return_if_fail(name      != NULL);
@@ -247,24 +143,11 @@
 
 	g_return_if_fail(status != NULL);
 
-	if (attr_id != NULL)
-	{
-		va_list args;
-
-		va_start(args, attr_id);
+	old_status = gaim_presence_get_active_status(presence);
 
-		while (attr_id != NULL)
-		{
-			set_value_from_arg(status, attr_id, &args);
-
-			attr_id = va_arg(args, char *);
-		}
-
-		va_end(args);
-	}
-
-	old_status = gaim_presence_get_active_status(presence);
-	gaim_presence_set_status_active(presence, status_id, TRUE);
+	va_start(args, status_id);
+	gaim_status_set_active_with_attrs(status, TRUE, args);
+	va_end(args);
 
 	list = gaim_find_buddies(account, name);
 	for (iter = list; iter != NULL; iter = iter->next)
--- a/src/prpl.h	Thu Mar 02 02:12:43 2006 +0000
+++ b/src/prpl.h	Thu Mar 02 04:51:09 2006 +0000
@@ -344,13 +344,11 @@
  *
  * @param account   The account the user is on.
  * @param status_id The status ID.
- * @param attr_id   The first attribute ID, or NULL for no attribute updates.
  * @param ...       A NULL-terminated list of attribute IDs and values,
  *                  beginning with the value for @a attr_id.
  */
 void gaim_prpl_got_account_status(GaimAccount *account,
-								  const char *status_id, const char *attr_id,
-								  ...);
+								  const char *status_id, ...);
 /**
  * Notifies Gaim that a user's idle state and time have changed.
  *
@@ -386,12 +384,11 @@
  * @param account   The account the user is on.
  * @param name      The screen name of the user.
  * @param status_id The status ID.
- * @param attr_id   The first attribute ID, or NULL for no attribute updates.
  * @param ...       A NULL-terminated list of attribute IDs and values,
  *                  beginning with the value for @a attr_id.
  */
 void gaim_prpl_got_user_status(GaimAccount *account, const char *name,
-							   const char *status_id, const char *attr_id, ...);
+							   const char *status_id, ...);
 /**
  * Informs the server that an account's status changed.
  *
--- a/src/status.c	Thu Mar 02 02:12:43 2006 +0000
+++ b/src/status.c	Thu Mar 02 04:51:09 2006 +0000
@@ -747,7 +747,9 @@
 									   const GList *attrs)
 {
 	gboolean changed = FALSE;
-	const gchar *id;
+	const GList *l;
+	GList *specified_attr_ids = NULL;
+	GaimStatusType *status_type;
 
 	g_return_if_fail(status != NULL);
 
@@ -767,26 +769,30 @@
 	status->active = active;
 
 	/* Set any attributes */
-	while (attrs)
+	l = attrs;
+	while (l != NULL)
 	{
+		const gchar *id;
 		GaimValue *value;
 
-		id = attrs->data;
-		attrs = attrs->next;
+		id = l->data;
+		l = l->next;
 		value = gaim_status_get_attr_value(status, id);
 		if (value == NULL)
 		{
 			gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is "
 							   "not supported.\n", id, status->type->name);
 			/* Skip over the data and move on to the next attribute */
-			attrs = attrs->next;
+			l = l->next;
 			continue;
 		}
 
+		specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
+
 		if (value->type == GAIM_TYPE_STRING)
 		{
-			const gchar *string_data = attrs->data;
-			attrs = attrs->next;
+			const gchar *string_data = l->data;
+			l = l->next;
 			if (((string_data == NULL) && (value->data.string_data == NULL)) ||
 				((string_data != NULL) && (value->data.string_data != NULL) &&
 				!strcmp(string_data, value->data.string_data)))
@@ -798,8 +804,8 @@
 		}
 		else if (value->type == GAIM_TYPE_INT)
 		{
-			int int_data = GPOINTER_TO_INT(attrs->data);
-			attrs = attrs->next;
+			int int_data = GPOINTER_TO_INT(l->data);
+			l = l->next;
 			if (int_data == value->data.int_data)
 				continue;
 			gaim_status_set_attr_int(status, id, int_data);
@@ -807,20 +813,48 @@
 		}
 		else if (value->type == GAIM_TYPE_BOOLEAN)
 		{
-			gboolean boolean_data = GPOINTER_TO_INT(attrs->data);
-			attrs = attrs->next;
+			gboolean boolean_data = GPOINTER_TO_INT(l->data);
+			l = l->next;
 			if (boolean_data == value->data.boolean_data)
 				continue;
-			gaim_status_set_attr_int(status, id, boolean_data);
+			gaim_status_set_attr_boolean(status, id, boolean_data);
 			changed = TRUE;
 		}
 		else
 		{
 			/* We don't know what the data is--skip over it */
-			attrs = attrs->next;
+			l = l->next;
 		}
 	}
 
+	/* Reset any unspecified attributes to their default value */
+	status_type = gaim_status_get_type(status);
+	l = gaim_status_type_get_attrs(status_type);
+	while (l != NULL)
+	{
+		GaimStatusAttr *attr;
+
+		attr = l->data;
+		if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp))
+		{
+			GaimValue *default_value;
+			default_value = gaim_status_attr_get_value(attr);
+			if (default_value->type == GAIM_TYPE_STRING)
+				gaim_status_set_attr_string(status, attr->id,
+						gaim_value_get_string(default_value));
+			else if (default_value->type == GAIM_TYPE_INT)
+				gaim_status_set_attr_int(status, attr->id,
+						gaim_value_get_int(default_value));
+			else if (default_value->type == GAIM_TYPE_BOOLEAN)
+				gaim_status_set_attr_boolean(status, attr->id,
+						gaim_value_get_boolean(default_value));
+			changed = TRUE;
+		}
+
+		l = l->next;
+	}
+	g_list_free(specified_attr_ids);
+
 	if (!changed)
 		return;
 	status_has_changed(status);
@@ -889,7 +923,6 @@
                                  "this!\n", id,
 				 gaim_status_type_get_name(gaim_status_get_type(status)));
 		return;
-				 				 
 	}
 	g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING);