# HG changeset patch
# Node ID ef4fe1d965d6
# Parent  44c107f92a65
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -225,6 +225,8 @@
 		  purple_request_field_get_field_type
 		* PurpleRoomlist is now a GObject. Please see the documentation for
 		  details.
+		* purple_request_field_list_get_icons now shows if list contains icons
+		* purple_request_field_list_get_items now returns list of PurpleKeyValuePair
 		* purple_roomlist_room_get_type is now
 		  purple_roomlist_room_get_room_type
 		* purple_roomlist_field_get_type is now
diff --git a/finch/gntrequest.c b/finch/gntrequest.c
--- a/finch/gntrequest.c
+++ b/finch/gntrequest.c
@@ -328,18 +328,20 @@
 			}
 			else if (type == PURPLE_REQUEST_FIELD_LIST)
 			{
-				GList *list = NULL, *iter;
+				GList *selected = NULL;
+				GList *list = purple_request_field_list_get_items(field);
 				if (purple_request_field_list_get_multi_select(field))
 				{
 					GntWidget *tree = purple_request_field_get_ui_data(field);
 
-					iter = purple_request_field_list_get_items(field);
-					for (; iter; iter = iter->next)
+					for (; list; list = list->next)
 					{
-						const char *text = iter->data;
+						PurpleKeyValuePair *item = list->data;
+						const char *text = item->key;
 						gpointer key = purple_request_field_list_get_data(field, text);
-						if (gnt_tree_get_choice(GNT_TREE(tree), key))
-							list = g_list_prepend(list, (gpointer)text);
+						if (gnt_tree_get_choice(GNT_TREE(tree), key)) {
+							selected = g_list_prepend(selected, (gpointer)text);
+						}
 					}
 				}
 				else
@@ -347,19 +349,19 @@
 					GntWidget *combo = purple_request_field_get_ui_data(field);
 					gpointer data = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo));
 
-					iter = purple_request_field_list_get_items(field);
-					for (; iter; iter = iter->next) {
-						const char *text = iter->data;
+					for (; list; list = list->next) {
+						PurpleKeyValuePair *item = list->data;
+						const char *text = item->key;
 						gpointer key = purple_request_field_list_get_data(field, text);
 						if (key == data) {
-							list = g_list_prepend(list, (gpointer)text);
+							selected = g_list_prepend(selected, (gpointer)text);
 							break;
 						}
 					}
 				}
 
-				purple_request_field_list_set_selected(field, list);
-				g_list_free(list);
+				purple_request_field_list_set_selected(field, selected);
+				g_list_free(selected);
 			}
 			else if (type == PURPLE_REQUEST_FIELD_ACCOUNT)
 			{
@@ -478,16 +480,15 @@
 create_list_field(PurpleRequestField *field)
 {
 	GntWidget *ret = NULL;
-	GList *list;
-	gboolean multi = purple_request_field_list_get_multi_select(field);
-	if (multi)
+	GList *list = purple_request_field_list_get_items(field);
+	if (purple_request_field_list_get_multi_select(field))
 	{
 		GntWidget *tree = gnt_tree_new();
 
-		list = purple_request_field_list_get_items(field);
 		for (; list; list = list->next)
 		{
-			const char *text = list->data;
+			PurpleKeyValuePair *item = list->data;
+			const char *text = item->key;
 			gpointer key = purple_request_field_list_get_data(field, text);
 			gnt_tree_add_choice(GNT_TREE(tree), key,
 					gnt_tree_create_row(GNT_TREE(tree), text), NULL, NULL);
@@ -500,10 +501,10 @@
 	{
 		GntWidget *combo = gnt_combo_box_new();
 
-		list = purple_request_field_list_get_items(field);
 		for (; list; list = list->next)
 		{
-			const char *text = list->data;
+			PurpleKeyValuePair *item = list->data;
+			const char *text = item->key;
 			gpointer key = purple_request_field_list_get_data(field, text);
 			gnt_combo_box_add_data(GNT_COMBO_BOX(combo), key, text);
 			if (purple_request_field_list_is_selected(field, text))
diff --git a/libpurple/protocols/silc/chat.c b/libpurple/protocols/silc/chat.c
--- a/libpurple/protocols/silc/chat.c
+++ b/libpurple/protocols/silc/chat.c
@@ -295,8 +295,10 @@
 	chpks = silc_buffer_alloc_size(2);
 
 	for (ct = 0; list; list = list->next, ct++) {
-		public_key = purple_request_field_list_get_data(f, list->data);
-		if (purple_request_field_list_is_selected(f, list->data)) {
+		PurpleKeyValuePair *item = list->data;
+
+		public_key = purple_request_field_list_get_data(f, item->key);
+		if (purple_request_field_list_is_selected(f, item->key)) {
 			/* Delete this public key */
 			pk = silc_public_key_payload_encode(public_key);
 			chpks = silc_argument_payload_encode_one(chpks, pk->data,
diff --git a/libpurple/request.h b/libpurple/request.h
--- a/libpurple/request.h
+++ b/libpurple/request.h
@@ -1618,7 +1618,7 @@
  *
  * Returns a list of items in a list field.
  *
- * Returns: (element-type utf8) (transfer none): The list of items.
+ * Returns: (element-type PurpleKeyValuePair) (transfer none): The list of items.
  */
 GList *purple_request_field_list_get_items(const PurpleRequestField *field);
 
@@ -1626,14 +1626,11 @@
  * purple_request_field_list_get_icons:
  * @field: The field.
  *
- * Returns a list of icons in a list field.
- *
- * The icons will correspond with the items, in order.
+ * Indicates if list field has icons.
  *
- * Returns: (element-type utf8) (transfer none): The list of icons or %NULL (i.e. the empty #GList)
- *          if no items have icons.
+ * Returns: TRUE if list field has icons, FALSE otherwise.
  */
-GList *purple_request_field_list_get_icons(const PurpleRequestField *field);
+gboolean purple_request_field_list_get_icons(const PurpleRequestField *field);
 
 /**************************************************************************/
 /* Label Field API                                                        */
diff --git a/libpurple/request.c b/libpurple/request.c
--- a/libpurple/request.c
+++ b/libpurple/request.c
@@ -99,7 +99,7 @@
 		struct
 		{
 			GList *items;
-			GList *icons;
+			gboolean has_icons;
 			GHashTable *item_data;
 			GList *selected;
 			GHashTable *selected_table;
@@ -955,7 +955,7 @@
 	}
 	else if (field->type == PURPLE_REQUEST_FIELD_LIST)
 	{
-		g_list_free_full(field->u.list.items, g_free);
+		g_list_free_full(field->u.list.items, (GDestroyNotify)purple_key_value_pair_free);
 		g_list_free_full(field->u.list.selected, g_free);
 		g_hash_table_destroy(field->u.list.item_data);
 		g_hash_table_destroy(field->u.list.selected_table);
@@ -1589,33 +1589,16 @@
 purple_request_field_list_add_icon(PurpleRequestField *field, const char *item, const char* icon_path,
 							void *data)
 {
+	PurpleKeyValuePair *kvp;
+
 	g_return_if_fail(field != NULL);
 	g_return_if_fail(item  != NULL);
 	g_return_if_fail(data  != NULL);
 	g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
 
-	if (icon_path)
-	{
-		if (field->u.list.icons == NULL)
-		{
-			GList *l;
-			for (l = field->u.list.items ; l != NULL ; l = l->next)
-			{
-				/* Order doesn't matter, because we're just
-				 * filing in blank items.  So, we use
-				 * g_list_prepend() because it's faster. */
-				field->u.list.icons = g_list_prepend(field->u.list.icons, NULL);
-			}
-		}
-		field->u.list.icons = g_list_append(field->u.list.icons, g_strdup(icon_path));
-	}
-	else if (field->u.list.icons)
-	{
-		/* Keep this even with the items list. */
-		field->u.list.icons = g_list_append(field->u.list.icons, NULL);
-	}
-
-	field->u.list.items = g_list_append(field->u.list.items, g_strdup(item));
+	field->u.list.has_icons = field->u.list.has_icons || (icon_path != NULL);
+	kvp = purple_key_value_pair_new_full(item, g_strdup(icon_path), g_free);
+	field->u.list.items = g_list_append(field->u.list.items, kvp);
 	g_hash_table_insert(field->u.list.item_data, g_strdup(item), data);
 }
 
@@ -1718,13 +1701,13 @@
 	return field->u.list.items;
 }
 
-GList *
+gboolean
 purple_request_field_list_get_icons(const PurpleRequestField *field)
 {
-	g_return_val_if_fail(field != NULL, NULL);
-	g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
-
-	return field->u.list.icons;
+	g_return_val_if_fail(field != NULL, FALSE);
+	g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, FALSE);
+
+	return field->u.list.has_icons;
 }
 
 PurpleRequestField *
diff --git a/pidgin/gtkrequest.c b/pidgin/gtkrequest.c
--- a/pidgin/gtkrequest.c
+++ b/pidgin/gtkrequest.c
@@ -1405,7 +1405,7 @@
 	GtkTreeViewColumn *column;
 	GtkTreeIter iter;
 	GList *l;
-	GList *icons = NULL;
+	gboolean icons;
 
 	icons = purple_request_field_list_get_icons(field);
 
@@ -1444,13 +1444,14 @@
 
 	for (l = purple_request_field_list_get_items(field); l != NULL; l = l->next)
 	{
-		const char *text = (const char *)l->data;
+		PurpleKeyValuePair *item = l->data;
+		const char *text = (const char *)item->key;
 
 		gtk_list_store_append(store, &iter);
 
 		if (icons)
 		{
-			const char *icon_path = (const char *)icons->data;
+			const char *icon_path = (const char *)item->value;
 			GdkPixbuf* pixbuf = NULL;
 
 			if (icon_path)
@@ -1461,7 +1462,6 @@
 						   1, text,
 						   2, pixbuf,
 						   -1);
-			icons = icons->next;
 		}
 		else
 			gtk_list_store_set(store, &iter,
